---
# System prepended metadata

title: 1103757 喬伊波伊 演算法作業8

---


# 1103757 喬伊波伊 演算法作業8
## 第1題: Voronoi Diagram
* 請畫出下圖兩個VD合併結果，畫出新建立的線段(註明為哪兩點的中垂線)，並說明簡述流程。
![](https://i.imgur.com/AV1PlWN.png)
![](https://i.imgur.com/dtKAiJs.png)
![](https://i.imgur.com/w7WNJMq.png)
![](https://i.imgur.com/NcIFBNR.png)
## 第2題: Voronoi Diagram的應用
* 請說明The Euclidean all nearest neighbor problem為何，以及如何應用VD來解此問題？

* * **The Euclidean all nearest neighbor problem：**
為平面上n個點，找出所有點的closed neighbor(different from closest pair problem)

* * **如何應用VD來解決此問題：**
我最近的鄰居一定會和我共用VD的edge
![](https://i.imgur.com/suSaMbd.jpg)
檢查每個中垂線對應到的兩點距離，找出最小的那個為最近鄰居。
## 第3題: FFT
* 當輸入為：{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16}，請說明如何應用FFT得到結果(只須說明計算過程，不用算出結果)？
![](https://i.imgur.com/IYFQ8RW.jpg)
## 第4題: 由Preorder與Inorder建構二元樹
* **解題思路：** 用preorder的數列當作root，之後再去inorder裡面分左右子樹，就這樣一直遞迴下去，直到葉節點(return nullptr)為止，然後先見左子樹在建右子樹。
* **程式碼：**
```cpp=
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
    int n=inorder.size()-1;
    int preordercheck=0;
    return construct(preorder,inorder,preordercheck,0,n); 
}
    TreeNode* construct(vector<int>& preorder,vector<int>& inorder,int& preordercheck,int left,int right){
    if(left>right) return nullptr;
    int flag=left;
    while(inorder[flag]!=preorder[preordercheck])flag++;
    preordercheck++;
    TreeNode* node=new TreeNode(inorder[flag]);
    node->left=construct(preorder,inorder,preordercheck,left,flag-1);
    node->right=construct(preorder,inorder,preordercheck,flag+1,right);
    return node;
}
```
* **測試輸出輸入的畫面截圖：**
![](https://hackmd.io/_uploads/BkNbMm7N2.png)

* **寫程式所花費的時間：** 40min
* **完成比例程度：** 自己的想法配上solution的linked list的寫法
## 第5題: 由Postorder與Inorder建構二元樹
* **解題思路：** 用postorder的最後面開始來當root，再配合inorder來區分左右子樹，就這樣一直遞迴下去，直到葉節點(return nullptr)為止，然後和上一題不同的是先見右子樹在建左子樹，基本上有了概念和上一題對linked list的練習，要自己寫這題不難。
* **程式碼：**
```cpp=
TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
    int n=inorder.size()-1;
    int postordercheck=postorder.size()-1;
    return construct(inorder,postorder,n,0,n);
}
TreeNode* construct(vector<int> inorder,vector<int> postorder,int& postordercheck,int left,int right){
    if(left>right) return nullptr;
    int flag=left; 
    while(postorder[postordercheck]!=inorder[flag]) flag++;
    postordercheck--;
    TreeNode* newNode=new TreeNode(inorder[flag]);
        
    newNode->right=construct(inorder,postorder,postordercheck,flag+1,right);
    newNode->left=construct(inorder,postorder,postordercheck,left,flag-1);
    return newNode;
}
```
* **測試輸出輸入的畫面截圖：**
![](https://hackmd.io/_uploads/Sy76cgr43.png)
* **寫程式所花費的時間：** 20min
* **完成比例程度：** 自己寫
## 第6題：由Pretorder與Postorder建構二元樹
* **解題思路：** 利用preorder來當root，再去找postorder來分出左右子樹，在遞迴直到nullptr為止，因為看leetcode上的solution看半天還不是很了解，所以這題有參考yt(https://www.youtube.com/watch?v=53aOi0Drp9I)的解法，寫成c++的版本比leetcode上的solution還容易理解。
* **程式碼：**
```cpp=
TreeNode* constructFromPrePost(vector<int>& preorder, vector<int>& postorder) {
    int n=preorder.size();
    return construct(preorder,postorder,0,0,n);
}
TreeNode* construct(vector<int>& preorder, vector<int>& postorder,int preoriginal,int postoriginal,int arrlen){
    if(arrlen<=0) return nullptr;
    TreeNode* node=new TreeNode(preorder[preoriginal]);
    if(arrlen==1) return node;
    int postind=postoriginal;
    while(postorder[postind]!=preorder[preoriginal+1]) postind++;
    int len=postind-postoriginal+1;
    node->left=construct(preorder,postorder,preoriginal+1,postoriginal,len);
    node->right=construct(preorder,postorder,preoriginal+len+1,postind+1,arrlen-len-1);
    return node;
}
```
* **測試輸出輸入的畫面截圖：**
![](https://hackmd.io/_uploads/BJ1l_zSE2.png)
* **寫程式所花費的時間：** 60min(包含看影片理解，跟寫出來)
* **完成比例程度：** 看yt理解後，改成c++版
## 心得：我覺得這次的作業程式題選得很漂亮，第一題其實概念就是資結有講過的，只要加上一些linked list的熟悉就可以寫出來，第二題只要第一題會寫，就一定很快就可以寫出來，第三題其實對我有點挑戰(可能是我太廢，還整天蹦重訓室上低卡)，直接看yt上的講解，理解後在自己寫，寫完發現比leetcode的c++ code還簡單易懂。