题目:由前序、中序遍历序列重建二叉树
虽然思路能想到,但是实际写却无从下手。。。
下面重现作者代码,多多实践。。。
#include<exception> //首先定义二叉树节点 struct BinaryTreeNode { int bt_Value; BinaryTreeNode* bt_pLeft; BinaryTreeNode* bt_pRight; }; //核心函数:ConstructCore(int* StartPreOrder, int* EndPreOrder, int* StartInOrder, int* EndInOrder); BinaryTreeNode* ConstructCore(int* StartPreOrder, int* EndPreOrder, int* StartInOrder, int* EndInOrder) //StartPreOrder,EndPreOrder为先序遍历序列的首尾;StartInOrder,EndInOrder为中序遍历序列的首尾 //总体思路:1、先序遍历首元素即为根节点,创建根节点; // 2、中序遍历中寻找根节点,以此为界,前面为左子树,后面为右子树; // 3、函数递归以创建左子树和右子树; // 递归终止条件:StartPreOrder == EndPreOrder时,StartInOrder同时应等于EndInOrder,为叶子节点。 //因Construct函数中已验证了各个指针项的合法性,所以ConstructCore不再验证。 { //根据前序序列首元素创建根节点 int RootValue = StartPreOrder[0]; BinaryTreeNode* root = new BinaryTreeNode; root->bt_Value = RootValue; root->bt_pLeft = root->bt_pRight = NULL; //递归终止条件 if(StartPreOrder == EndPreOrder) { if(StartInOrder == EndInOrder && *StartPreOrder == *StartInOrder) return root; //该节点为叶子节点,创建子树结束 else throw std::exception("Invalid Input!"); } //在中序序列中寻找根节点位置 int* rootInOrder = StartInOrder; while(rootInOrder <= EndInOrder && *rootInOrder != RootValue) rootInOrder++; if(rootInOrder > EndInOrder) throw std::exception("Invalid Input!"); //确定左子树的节点个数 int LeftTreeLength = rootInOrder - StartInOrder; int* LeftTreePreOrderEnd = StartPreOrder + LeftTreeLength; //创建左子树 if(LeftTreeLength > 0 ) root->bt_pLeft = ConstructCore(StartPreOrder+1,LeftTreePreOrderEnd,StartInOrder,rootInOrder-1); //创建右子树 if(rootInOrder < EndInOrder) root->bt_pRight = ConstructCore(LeftTreePreOrderEnd+1,EndPreOrder,rootInOrder+1,EndInOrder); return root; } //调用该递归函数的Construct函数如下: BinaryTreeNode* Construct(int* PreOrder, int* InOrder, int length) { if(PreOrder == NULL || InOrder == NULL || length <= 0) return NULL; return ConstructCore(PreOrder,PreOrder+length-1,InOrder,InOrder+length-1); }
//BinaryTree.cpp中的各个接口实现 //1. 创建二叉树节点 BinaryTreeNode* CreateBinaryTreeNode(int value) { BinaryTreeNode* pNode = new BinaryTreeNode; pNode->bt_Value = value; pNode->bt_pLeft = pNode->bt_pRight = NULL; return pNode; } //2. 连接树节点 void ConnectBinaryTreeNodes(BinaryTreeNode* pParent, BinaryTreeNode* pLeft, BinaryTreeNode* pRight) { if(pParent != NULL) { pParent->bt_pLeft = pLeft; pParent->bt_pRight = pRight; } else return; } //3. 打印树节点及其孩子节点 void PrintTreeNode(BinaryTreeNode* pNode) { if(pNode != NULL) { cout<<"The value of this node is: "<<pNode->bt_Value <<endl; if(pNode->bt_pLeft != NULL) cout<<"The value of the left-child node is: "<<pNode->bt_pLeft->bt_Value <<endl; else cout<<"The left-child node is NULL!"<<endl; if(pNode->bt_pRight != NULL) cout<<"The value of the right-child node is: "<<pNode->bt_pRight->bt_Value <<endl; else cout<<"The right-child node is NULL!"<<endl; } else cout<<"This node is NULL!"<<endl; } //4. 打印树 (逐三角打印) void PrintTree(BinaryTreeNode* pRoot) { PrintTreeNode(pRoot); if(pRoot != NULL) { if(pRoot->bt_pLeft != NULL) PrintTree(pRoot->bt_pLeft); if(pRoot->bt_pRight != NULL) PrintTree(pRoot->bt_pRight); } } //5. 销毁树 void DestroyTree(BinaryTreeNode* pRoot) { if(pRoot != NULL) { BinaryTreeNode* pLeft = pRoot->bt_pLeft; BinaryTreeNode* pRight = pRoot->bt_pRight; delete pRoot; pRoot = NULL; DestroyTree(pLeft); DestroyTree(pRight); } }