对于一颗二叉树,能够根据先序遍历(后序遍历)和中序遍历从新还原出二叉树。node
根据先序遍历和中序遍历还原二叉树的主要思想:ios
一、先序遍历序列的第一个元素一定是根节点,能够由此获取二叉树的根节点。函数
二、根据根节点,在中序遍历序列中查找该节点,由中序遍历的性质可知,中序遍历中该根节点左边的序列一定在根节点的左子树中,而根节点右边的序列一定在右子树中。由此能够知道先序遍历中左子树以及右子树的起止位置。ui
三、分别对左子树和右子树重复上述的过程,直至全部的子树的起止位置相等时,说明已经到达叶子节点,遍历完毕。spa
代码以下:code
#ifndef __FUNCTION_H__ #define __FUNCTION_H__ #include <iostream> using namespace std; struct BinaryTreeNode { int nodeValue; BinaryTreeNode *pLeft; BinaryTreeNode *pRight; }; BinaryTreeNode * BuildRecursivly(int *pPrevOrderStart, int *pPrevOrderEnd, int *pInOrderStart, int *pInOrderEnd) { //在先序遍历序列中取出第一个元素即为根节点元素 int value = pPrevOrderStart[0]; //构造根节点 BinaryTreeNode *root = new BinaryTreeNode; root->nodeValue = value; root->pLeft = root->pRight = NULL; //递归结束的状况,即只剩一个叶子节点 if(pPrevOrderStart == pPrevOrderEnd) { if(pInOrderStart == pInOrderEnd && *pPrevOrderStart == *pInOrderStart) return root; else throw std::exception(); } //在中序遍历序列中找出根节点的位置 int *pInOrderCursor = pInOrderStart; while(pInOrderCursor < pInOrderEnd && *pInOrderCursor != value) { pInOrderCursor++; } if(pInOrderCursor == pInOrderEnd && *pInOrderCursor != value) { throw std::exception(); } //取得左子树的长度以及在先序遍历中取得左子树的起始位置 int leftTreeLen = pInOrderCursor - pInOrderStart; int *pPrevOrderLeftTreeEnd = pPrevOrderStart + leftTreeLen; //若是左子树存在,则递归左子树 if(leftTreeLen > 0) { root->pLeft = BuildRecursivly(pPrevOrderStart+1, pPrevOrderLeftTreeEnd, pInOrderStart, pInOrderCursor-1); } //若是右子树存在,则递归右子树 if((pPrevOrderEnd-pPrevOrderStart) > leftTreeLen) { root->pRight = BuildRecursivly(pPrevOrderLeftTreeEnd+1, pPrevOrderEnd, pInOrderCursor+1, pInOrderEnd); } return root; } BinaryTreeNode * BulidBinaryTree(int *szPrevOrder, int *szInOrder, int nodeNum) { if(szPrevOrder == NULL || szInOrder == NULL) return NULL; return BuildRecursivly(szPrevOrder, szPrevOrder+nodeNum-1, szInOrder, szInOrder+nodeNum-1); } /*先序遍历*/ void PrevOrder(BinaryTreeNode *root) { if(root == NULL) return; //根 cout<<root->nodeValue<<' '; //左子树 if(root->pLeft != NULL) PrevOrder(root->pLeft); //右子树 if(root->pRight != NULL) PrevOrder(root->pRight); } /*中序遍历*/ void InOrder(BinaryTreeNode *root) { if(root == NULL) return; //左子树 if(root->pLeft != NULL) InOrder(root->pLeft); //根 cout<<root->nodeValue<<' '; //右子树 if(root->pRight != NULL) InOrder(root->pRight); } /*后序遍历*/ void PostOrder(BinaryTreeNode *root) { if(root == NULL) return; //左子树 if(root->pLeft != NULL) PostOrder(root->pLeft); //右子树 if(root->pRight != NULL) PostOrder(root->pRight); //根 cout<<root->nodeValue<<' '; } #endif
主函数:递归
#include <iostream> #include "function.h" using namespace std; /*重建二叉树*/ int main() { int szPrevOrder[] = {1, 2, 4, 7, 3, 5, 6, 8}; //二叉树的先序遍历 int szInOrder[] = {4, 7, 2, 1, 5, 3, 8, 6}; //二叉树的中序遍历 int nodeNum = sizeof(szPrevOrder)/sizeof(int); BinaryTreeNode *root = BulidBinaryTree(szPrevOrder, szInOrder, nodeNum); cout<<"PrevOrder: "; PrevOrder(root); cout<<endl<<"InOrder: "; InOrder(root); cout<<endl<<"PostOrder: "; PostOrder(root); cout<<endl; return 0; }