劍指Offer 面試題06 重建二叉樹

2021-08-03 17:49:26 字數 2891 閱讀 8203

輸入某二叉樹的前序遍歷和中序遍歷的結果,請重建出該二叉樹。假設輸入的前序遍歷和中序遍歷的結果中都不含重複的數字。例如輸入前序遍歷序列和中序遍歷序列,則重建二叉樹並返回。

先序:中序:

分析一波:先手動重建一次二叉樹,找到重建的規律。首先我們取先序序列第一位作為根節點,然後在中序序列中找到它,則中序序列左邊的為左子樹中序序列,右邊的為右子樹中序序列,以此類推,典型的遞迴思想。

要想實現遞迴解決,必須每次找到左子樹的先序序列、中序序列,右子樹的先序序列、中序序列。而關鍵是:

1.首先取先序序列首元素,先序序列首元素必為當前樹的根結點元素;

2.根據根結點元素,將中序序列分割為兩個區域,左邊為左子樹中序序列,右邊為右子樹中序序列;

3.根據各個子樹中序序列的長度,可以截取出各個子樹的先序序列(因為長度一致且每個子樹的先序序列是在一起的長度為中序序列長度);

4.遞迴,如果序列長度為0則返回null。

根據這一思想,敲了一上午的**,基本解決。有兩個版本的函式,引數不同,分別對應劍指offer原書和牛客網oj版本。

#include #include #include using namespace std;

/*** definition for binary tree

**/struct treenode

};//劍指offer原書版,根據先序遍歷序列、中序遍歷序列重建二叉樹

treenode* constructbyprein(int *preorder, int *inorder, int length)

} //中序序列中,根節點左邊的為左子樹,右邊的為右子樹

int *leftpre = preorder + 1;

int *leftin = inorder;

int *rightpre = preorder + leftlength + 1;

int *rightin = inorder + leftlength + 1;

//遞迴構建左右子樹

root->left = constructbyprein(leftpre, leftin, leftlength);

root->right = constructbyprein(rightpre, rightin, rightlength);

return root;

}//牛客網版本,根據先序中序序列重建二叉樹

treenode* reconstructbinarytree(vectorpreorder, vectorinorder)

} //中序序列中,根節點左邊的為左子樹,右邊的為右子樹

vectorleftpre (preorder.begin() + 1, preorder.begin() + 1 + leftlength);

vectorleftin (inorder.begin(), inorder.begin() + leftlength);

vectorrightpre (preorder.begin() + leftlength + 1, preorder.begin() + leftlength + 1 + rightlength);

vectorrightin (inorder.begin() + leftlength + 1, inorder.begin() + leftlength + 1 + rightlength);

//遞迴構建左右子樹

root->left = reconstructbinarytree(leftpre, leftin);

root->right = reconstructbinarytree(rightpre, rightin);

return root;

}//先序遍歷

void preorder(treenode *root)

//中序遍歷

void inorder(treenode *root)

//後序遍歷

void postorder(treenode *root)

int main()

; int inorder = ;

treenode *tree = constructbyprein(preorder, inorder, 8);

preorder(tree); //先序輸出

std::cout << std::endl;

inorder(tree); //中序輸出

std::cout << std::endl;

//牛客網版本函式測試

vectorpre = ;

vectorin = ;

treenode *tree2 = reconstructbinarytree(pre, in);

preorder(tree2); //先序輸出

std::cout << std::endl;

inorder(tree2); //中序輸出

std::cout << std::endl;

system("pause");

return 0;

}

牛客網oj通過測試,1ms。本地測試結果:

順便實現一下二叉樹層序遍歷,層序遍歷需要借助佇列實現,這裡採用兩種方法1.stl的deque,2.陣列模擬佇列,**如下:

#include using namespace std;

//層序遍歷

void levelorder(treenode *root)

}//層序遍歷陣列模擬佇列

void levelorder2(treenode *root)

if (node->right != null)}}

劍指offer 面試題6 重建二叉樹

題目 輸入某二叉樹的前序遍歷和中序遍歷,請重建出該二叉樹。假設輸入的前序遍歷和中序遍歷的結果中都不含有重複的數字。例如,前序遍歷序列 1,2,4,7,3,5,6,8 中序遍歷序列 4,7,2,1,5,3,8,6 則重建出的二叉樹如下所示,並輸出它的頭結點1。基本思想 前序遍歷 前序遍歷首先訪問根結點...

劍指offer《面試題6 重建二叉樹》

題目 輸入某二叉樹的前序遍歷和中序遍歷的結果,請重建該二叉樹。假設輸入的前序遍歷和中序遍歷的結果中都不含重複的數字。例如輸入前序遍歷序列和中序遍歷序列,則重建出下圖所示的二叉樹並輸出它的頭結點。1 2 3 4 5 6 7 8 劍指offer 名企面試官精講典型程式設計題 著作權所有者 何海濤 inc...

劍指offer 面試題6重建二叉樹

輸入某二叉樹的前序遍歷和中序遍歷的結果,請重建出該二叉樹。假設輸入的前序遍歷和中序遍歷的結果中都不含重複的數字。重建出二叉樹,並輸出根節點。二叉樹的定義如下 如上,前序遍歷 1,2,4,7,3,5,6,8,中序 4,7,2,1,5,3,8,6,後序遍歷 7,4,2,5,8,6,3,1 在二叉樹的前序...