重建二叉树

来源:互联网 发布:湖南医药学院网络教学 编辑:程序博客网 时间:2024/04/30 18:25

题目:

        输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。

思路:

        在二叉树的前序遍历序列中,第一个数字总是树的根节点的值。但是中序遍历序列中,根节点的值在序列的中间,左子树的节点的值位于根节点的值的左边,而右子树的节点的值位于根节点的值的右边。因此我们需要扫描中序遍历序列,才能找到根节点的值。

        程序的难点在于如何判断输入的数据无效。

程序如下:

#include <iostream>#include <stdio.h>#include <stdlib.h>using namespace std;struct BinaryTreeNode {int m_nValue;struct BinaryTreeNode *m_pLeft;struct BinaryTreeNode *m_pRight;};BinaryTreeNode* Construct(int *preorder, int *inorder, int lenght);BinaryTreeNode* ConstructCore(int *startPreorder, int *endPreorder, int *startInorder, int *endInorder);//后序遍历void Traverse( BinaryTreeNode * root){if (root == NULL) {return;}else{Traverse(root->m_pRight);cout << root->m_nValue;Traverse(root->m_pLeft);}}int main(int argc, char* argv[]){int preOrder[] = {5, 4, 2, 1, 6, 3};int inOrder[] = {2, 4, 1, 6, 5, 3};BinaryTreeNode *head = Construct(preOrder, inOrder, sizeof(inOrder) / sizeof(inOrder[0]));cout << "后序遍历的结果:" << endl;Traverse(head);cout << endl;return 0;}BinaryTreeNode* Construct(int *preorder, int *inorder, int lenght){if (preorder == NULL || inorder == NULL || lenght <= 0) {return NULL;}return ConstructCore(preorder, preorder + lenght - 1, inorder, inorder + lenght - 1);}BinaryTreeNode* ConstructCore(int *startPreorder, int *endPreorder, int *startInorder, int *endInorder){int rootValue = startPreorder[0];BinaryTreeNode *root = new BinaryTreeNode();root->m_nValue = rootValue;root->m_pLeft = root->m_pRight = NULL;if (startPreorder == endPreorder) {//先序遍历已经结束了,那这个时候一定是插入最后一个节点,则应该满足下面的if语句,否则输入的数据有误if (startInorder == endInorder && *startPreorder == *startInorder) {return root;}else{cout << "Invalid input" << endl;exit(-1);}}int *rootInorder = startInorder;while (rootInorder <= endInorder && *rootInorder != rootValue) {++rootInorder;}if (rootInorder <= endInorder && *rootInorder != rootValue) {cout << "Invalid input" << endl;exit(-1);}int leftLength = rootInorder - startInorder;int *leftPreorderEnd = startPreorder + leftLength;if (leftLength > 0) {root->m_pLeft = ConstructCore(startPreorder + 1, leftPreorderEnd, startInorder, rootInorder - 1);}if (leftLength < endPreorder - startPreorder) {root->m_pRight = ConstructCore(leftPreorderEnd + 1, endPreorder, rootInorder + 1, endInorder);}return root;}

参考资料:何海涛,《剑指offer》