1.根据先序遍历和中序遍历重建二叉树
-
先序遍历第一个总是根节点,中序遍历根节点在中间,左边为左子树,右边为右子树
-
根据上述特性,每次能找到当前根节点,以及划分出左右子树,递归构建左右子树即可构建整个树
-
example(红色根节点,黑色左子树,绿色右子树)
1 / \ 2 3 / / \ 4 5 6 \ / 7 8
先序:1 2 4 7 3 5 6 8
中序:4 7 2 1 5 3 8 6
2.代码
#include <stdio.h> #include <exception> struct BinaryTreeNode { int value; BinaryTreeNode* left; BinaryTreeNode* right; }; BinaryTreeNode* doConstruct(int* startPreOrder, int* endPreOrder, int* startMidOrder, int* endMidOrder); BinaryTreeNode* construct(int* preOrder, int* midOrder, int length) { if(preOrder==NULL || midOrder==NULL || length<=0) return NULL; do_construct(preOrder, preOrder+length-1, midOrder, midOrder+length-1); } BinaryTreeNode* doConstruct(int* startPreOrder, int* endPreOrder, int* startMidOrder, int* endMidOrder) { BinaryTreeNode* root = new BinaryTreeNode(); root->value = startPreOrder[0];//先序第一个就是根节点 root->left = root->right = NULL; if(startPreOrder == endPreOrder) { if(startMidOrder==endMidOrder && startPreOrder[0]==startMidOrder[0]) //那么中序也必须只有一个元素,并且先序中序一致 return root; else throw std::exception("Invalid input."); } //在中序遍历中寻找根节点 int* findRoot = startMidOrder; while(findRoot<=endMidOrder && *findRoot!=root->value) findRoot ++; if(findRoot==endMidOrder && *findRoot!=root->value) //都中序末尾了,还没找到根节点 throw std::exception("Invalid input."); int leftTreeLength = findRoot - startMidOrder; if(leftTreeLength > 0) //有左子树 { root->left = doConstruct(startPreOrder+1, startPreOrder+leftTreeLength, startMidOrder, findRoot-1); } if(findRoot != endMidOrder) //有右子树 { root->right = doConstruct(startPreOrder+leftTreeLength+1, endPreOrder, findRoot+1, endMidOrder); } return root; } void printTree(BinaryTreeNode* root) {//打印后序遍历 if(root != NULL) { if(root->left != NULL) PrintTree(root->left); if(root->right != NULL) PrintTree(root->right); printf("%d ", root->value); } } int main() { // 普通二叉树 // 1 // / \ // 2 3 // / / \ // 4 5 6 // \ / // 7 8 // int length = 8; // int preorder[8] = {1, 2, 4, 7, 3, 5, 6, 8}; // int inorder[8] = {4, 7, 2, 1, 5, 3, 8, 6}; // 完全二叉树 // 1 // / \ // 2 3 // / \ / \ // 4 5 6 7 const int length = 7; int preorder[length] = {1, 2, 4, 5, 3, 6, 7}; int inorder[length] = {4, 2, 5, 1, 6, 3, 7}; BinaryTreeNode* root = construct(preorder, inorder, length); printTree(root); return 0; }