劍指offer 7:重建二叉樹

寫在最前

因爲各種各樣的原因,要開始準備春招,所以開始刷劍指offer(第二版)。

題意

輸入某二叉樹的前序遍歷和中序遍歷的結果,請重建出該二叉樹。假設輸入的前序遍歷和中序遍歷的結果中都不含重複的數字。例如輸入前序遍歷序列{1,2,4,7,3,5,6,8}和中序遍歷序列{4,7,2,1,5,3,8,6},則重建二叉樹並返回。

這個是個二叉樹很基礎的題啦,需要用遞歸來實現。主要講解在書的62頁,主要貼自己的代碼和自己的理解。

主要利用的規律如下圖:

利用前序中序構建二叉樹

代碼

//這裏我們遞歸開始之前傳入的是整個pre和in數組,然後在之後的遞歸中再改變pre和in的大小
struct TreeNode *test(int *pre_start, int *pre_end, int *in_start, int *in_end) {
    //創建一個節點並malloc
    struct TreeNode *root = (struct TreeNode *) malloc(sizeof(struct TreeNode));
    //把這個節點賦值爲當前的pre的第一個數,因爲根據規律,這個數是根節點
    root->val = *pre_start;
    root->left = NULL;
    root->right = NULL;
    //如果首尾相等,說明到了遞歸最後的終止條件了,只有一個節點了,就返回這個節點
    if (pre_end == pre_start)
        return root;
    //然後我們在中序遍歷的數組中要找到和前序遍歷根節點相等的節點,然後記下到這個節點的長度,這個長度就是左子樹的長度
    //就是根據上圖找到左右子樹,然後再構建
    int left_len = 0;
    for (int i = 0; i <= (in_end - in_start); i++)
        if (in_start[i] == root->val) {
            left_len = i;
            break;
        }
    //如果左子樹的長度大於0,就構建左子樹
    if (left_len > 0)
        root->left = test(pre_start + 1, pre_start + left_len, in_start, in_start + left_len - 1);
    //右子樹大於0就構建右子樹
    if (in_end - in_start >= left_len + 1)
        root->right = test(pre_start + left_len + 1, pre_end, in_start + left_len + 1, in_end);
    //最後返回構建的根節點
    return root;
}


class Solution {
public:
    //題目給的要求傳進來的參數是兩個vector,所以想要做遞歸,還需要改成數組形式纔可以
    TreeNode *reConstructBinaryTree(vector<int> pre, vector<int> vin) {
        //&pre[0]就是把vector直接變成數組。然後傳入到遞歸函數中
        return test(&pre[0],&pre[0]+pre.size()-1,&vin[0],&vin[0]+vin.size()-1);
    }
};

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章