重建二叉树(剑指offer6、编程之美3.9)
2014-04-27 20:28
323 查看
题目:1.给出二叉树的前序和中序遍历序列,构建出这个二叉树;2.根据二叉树的中序和后序遍历序列,构建出这个二叉树;遍历序列中没有重复的结点值。
问:假如遍历序列中含有相同的结点值时,如和求解?
1.根据前序和中序序列构建二叉树。思路:易知前序序列中的第一个结点即为二叉树的根结点,而此结点在中序序列中将二叉树的结点分为两部分,其左边部分即为左子树中的各个结点,其有边部分即为右子树中的各个结点,根据这些我们可以得到左右子树中分别有多少个结点,假设左子树中有left个结点,右子树中有right个结点,进而又可以将先序序列分为两部分,根结点后面的left个结点即为左子树中的结点,最后面的right个结点即为右子树中的结点。利用递归可以重复求解,最终得到我们期望的二叉树结果。
2.根据二叉树的中序和后序遍历序列,构造二叉树。思路:利用前面的思路,很容易得到下面这个结果。
测试代码
注:部分内容参考自剑指offer和编程之美
问:假如遍历序列中含有相同的结点值时,如和求解?
1.根据前序和中序序列构建二叉树。思路:易知前序序列中的第一个结点即为二叉树的根结点,而此结点在中序序列中将二叉树的结点分为两部分,其左边部分即为左子树中的各个结点,其有边部分即为右子树中的各个结点,根据这些我们可以得到左右子树中分别有多少个结点,假设左子树中有left个结点,右子树中有right个结点,进而又可以将先序序列分为两部分,根结点后面的left个结点即为左子树中的结点,最后面的right个结点即为右子树中的结点。利用递归可以重复求解,最终得到我们期望的二叉树结果。
//根据二叉树前序和中序遍历构造二叉树 BinaryTreeNode* constructBT(int* preorder, int* inorder, int length) { if (NULL == preorder || NULL == inorder || 0 >= length) { return NULL; } return constructBTByPreInOrder(preorder, preorder + length - 1, inorder, inorder + length - 1); } //根据二叉树前序和中序遍历构造二叉树 BinaryTreeNode* constructBTByPreInOrder(int* startPreorder, int* endPreorder, int* startInorder, int* endInorder) { if (NULL == startPreorder || NULL == endPreorder || NULL == startInorder || NULL == endInorder) { return NULL; } //创建根结点 int rootValue = startPreorder[0]; BinaryTreeNode* root = new BinaryTreeNode(); root->m_nValue = rootValue; root->m_pLeftChild = NULL; root->m_pRightChild = NULL; //在中序序列中找到根结点 int* rootInorder = startInorder; for (; rootInorder <= endInorder; ++rootInorder) { if (rootValue == *rootInorder) { break; } } //分别求得左右子树的结点数 int leftChildLength = rootInorder - startInorder; int rightChildLength = endInorder - rootInorder; //构建左子树 if (0 < leftChildLength) { root->m_pLeftChild = constructBTByPreInOrder(startPreorder + 1, startPreorder + leftChildLength, startInorder, rootInorder - 1); } //构建右子树 if (0 < rightChildLength) { root->m_pRightChild = constructBTByPreInOrder( startPreorder + leftChildLength + 1, endPreorder, rootInorder + 1, endInorder); } return root; }
2.根据二叉树的中序和后序遍历序列,构造二叉树。思路:利用前面的思路,很容易得到下面这个结果。
//根据二叉树中序和后序遍历构造二叉树 BinaryTreeNode* constructBT(int* inorder, int* postorder, int length) { if (NULL == inorder || NULL == postorder || 0 >= length) { return NULL; } return constructBTByInPostOrder(inorder, inorder + length - 1, postorder, postorder + length - 1); } BinaryTreeNode* constructBTByInPostOrder(int* startInorder, int* endInorder, int* startPostOrder, int* endPostOrder) { if (NULL == startInorder || NULL == endInorder || NULL == startPostOrder || NULL == endPostOrder) { return NULL; } //根据后序遍历得到根结点 int rootValue = endPostOrder[0]; BinaryTreeNode* root = new BinaryTreeNode(); root->m_nValue = rootValue; root->m_pLeftChild = NULL; root->m_pRightChild = NULL; //在中序序列中找根结点 int* rootInorder = startInorder; for (; rootInorder <= endInorder; ++rootInorder) { if (rootValue == *rootInorder) { break; } } //分别计算左右子树中的结点数目 int leftChildCount = rootInorder - startInorder; int rightChildCount = endInorder - rootInorder; //构建左右子树 if (0 < leftChildCount) { root->m_pLeftChild = constructBTByInPostOrder(startInorder, rootInorder - 1, startPostOrder, startPostOrder + leftChildCount - 1); } //构建右孩子 if (0 < rightChildCount) { root->m_pRightChild = constructBTByInPostOrder(rootInorder + 1, endInorder, startPostOrder + leftChildCount, endPostOrder - 1); } return root; }
测试代码
#include <stddef.h> #include <iostream> using namespace std; int main() { int n = 0; cout << "输入测试数据的组数:" << endl; cin >> n; while (n > 0) { cout << "输入序列长度:" << endl; int len = 0; cin >> len; int *x = new int[len]; int *y = new int[len]; cout << "输入先(中)序序列:" << endl; for (int i = 0; i < len; ++i) { cin >> x[i]; } cout << "输入中(后)序序列:" << endl; for (int i = 0; i < len; ++i) { cin >> y[i]; } BinaryTreeNode* binaryTreeNode = constructBT(x, y, len); cout << "二叉树前序遍历(递归):" << endl; preorderTravesal(binaryTreeNode); cout << endl; cout << "二叉树的后序遍历(递归):" << endl; postorderTravesal(binaryTreeNode); cout << endl; delete x; delete y; --n; } return 0; }
注:部分内容参考自剑指offer和编程之美
相关文章推荐
- 《编程之美》3.9重建二叉树
- 剑指offer 重建二叉树
- 编程之美:第三章 结构之法 3.9重建二叉树
- 【剑指offer】面试题 7:重建二叉树
- 剑指Offer-4.重建二叉树
- [牛客网,剑指offer,python] 重建二叉树
- 剑指offer 面试题6:重建二叉树(Leetcode105. Construct Binary Tree from Preorder and Inorder Traversal) 解题报告
- 剑指offer 6 重建二叉树
- 剑指offer-算法题练习:part4 重建二叉树
- 编程之美系列: 3.9 重建二叉树
- 【剑指Offer】面试题6:重建二叉树
- 剑指offer-4.重建二叉树
- 剑指offer 面试题6 重建二叉树2
- (C++)剑指offer-4:重建二叉树(理解不透彻)
- 剑指offer——重建二叉树
- 剑指offer——题目1385:重建二叉树
- 【剑指offer】面试题6:重建二叉树
- [牛客网,剑指offer,python] 重建二叉树
- 剑指offer面试题5-从尾到头打印链表/6-重建二叉树
- 剑指offer——重建二叉树