遍历重构
- 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。
- 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。
- 把一个有序整数数组放到一棵二叉树中,要求树的高度最小。
1、思路:
前序遍历的第一个是根结点,在中序遍历中找到该结点,则该结点左侧是左子树的范围,右侧是右子树的范围。由该范围再去前序遍历数组中圈定同样个数的左右子树。同理递归处理左右子树。
Construct
1 BinaryTreeNode* Construct(int* preorder, int* inorder, int length) 2 { 3 if(preorder == NULL || inorder == NULL || length <= 0) 4 return NULL; 5 6 return ConstructCore(preorder, preorder + length - 1, 7 inorder, inorder + length - 1); 8 } 9 10 BinaryTreeNode* ConstructCore 11 ( 12 int* startPreorder, int* endPreorder, 13 int* startInorder, int* endInorder 14 ) 15 { 16 // 前序遍历序列的第一个数字是根结点的值 17 int rootValue = startPreorder[0]; 18 BinaryTreeNode* root = new BinaryTreeNode(); 19 root->m_nValue = rootValue; 20 root->m_pLeft = root->m_pRight = NULL; 21 22 if(startPreorder == endPreorder) 23 { 24 if(startInorder == endInorder && *startPreorder == *startInorder) 25 return root; 26 else 27 throw std::exception("Invalid input."); 28 } 29 30 // 在中序遍历中找到根结点的值 31 int* rootInorder = startInorder; 32 while(rootInorder <= endInorder && *rootInorder != rootValue) 33 ++ rootInorder; 34 35 if(rootInorder == endInorder && *rootInorder != rootValue) 36 throw std::exception("Invalid input."); 37 38 int leftLength = rootInorder - startInorder; 39 int* leftPreorderEnd = startPreorder + leftLength; 40 if(leftLength > 0) 41 { 42 // 构建左子树 43 root->m_pLeft = ConstructCore(startPreorder + 1, leftPreorderEnd, 44 startInorder, rootInorder - 1); 45 } 46 if(leftLength < endPreorder - startPreorder) 47 { 48 // 构建右子树 49 root->m_pRight = ConstructCore(leftPreorderEnd + 1, endPreorder, 50 rootInorder + 1, endInorder); 51 } 52 53 return root; 54 }
2、思路:
二叉搜索树的特点是左子树的所有元素比根节点小,右子树的所有元素比根节点大。由根节点找到左右子树的范围,并判断是否负责大小性质。
VerifySquenceOfBST
1 bool VerifySquenceOfBST(int sequence[], int length) 2 { 3 if(sequence == NULL || length <= 0) 4 return false; 5 6 int root = sequence[length - 1]; 7 8 // 在二叉搜索树中左子树的结点小于根结点 9 int i = 0; 10 for(; i < length - 1; ++ i) 11 { 12 if(sequence[i] > root) 13 break; 14 } 15 16 // 在二叉搜索树中右子树的结点大于根结点 17 int j = i; 18 for(; j < length - 1; ++ j) 19 { 20 if(sequence[j] < root) 21 return false; 22 } 23 24 // 判断左子树是不是二叉搜索树 25 bool left = true; 26 if(i > 0) 27 left = VerifySquenceOfBST(sequence, i); 28 29 // 判断右子树是不是二叉搜索树 30 bool right = true; 31 if(i < length - 1) 32 right = VerifySquenceOfBST(sequence + i, length - i - 1); 33 34 return (left && right); 35 }
3、思路:
递归对半处理数组,每次取中间节点作为root,左半部分和右半部分分别作为左右孩子。
1 TreeNode* Array2TreeCore(int data[], int start, int end) 2 { 3 if (start > end) return NULL; 4 int mid = (start + end) / 2; 5 TreeNode* root = new TreeNode(data[mid]); 6 root->left = Array2TreeCore(data, start, mid - 1); 7 root->right = Array2TreeCore(data, mid + 1, end); 8 return root; 9 } 10 11 TreeNode* Array2Tree(int data[], int len) 12 { 13 if (data == NULL || len < 0) return NULL; 14 return Array2TreeCore(data, 0, len - 1); 15 }