重建二叉树
2015-12-02 14:04
253 查看
题目
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中不含有重复地数字。例如输入的前序遍历序列{1 , 2 , 4 , 7 , 3, 5 , 6 , 8}和中序遍历序列{4 , 7 , 2 , 1 , 5 , 3 , 8 , 6},则重建出下图1所示的二叉树并输出它的头结点。(1) / \ (2) (3) / / \ (4) (5) (6) \ / (7) (8) 图1
分析
在二叉树的前序遍序列中,第一个数字总是树的根结点的值。但在中序遍历序列中,根结点的值在序列的中间,左子树的结点的值位于根结点的值的左边,而右子树的结点的值位于根结点的值的右边。因此需要扫描中序遍历序列,才能找到根结点的值。如上图,前序遍历序列的第一个数字1就是根结点的值。扫面中序遍历序列,就能确定根结点的值的位置。根据中序遍历序列特点,在根结点的值1前面的数字都是左子树结点的值,位于1后面的数字都是右子树结点的值。
由于中序遍历序列中,有3个数字是左子树结点的值,因此左子树总共有3个有3个做子结点。同样,在前序遍历序列中,根结点后面的3个数字就是3个左子树的结点的值,在后面的所有数字都是右子树结点的值。这样就在前序和中序这两个遍历中,分别找到左右子树的对应的子序列。
代码
#include<stdio.h> #include<iostream> #include <exception> using namespace std; typedef int ElemType; typedef struct BiTNode { ElemType data; //结点的数据域 struct BiTNode *lchild, *rchild; //左右孩子 }BiTNode, *BiTree; /*递归的调用constructCore去构造左右子数*/ BiTree constructCore(int* sPreorder, int* ePreorder, int* sInorder, int* eInorder){ //前序遍历序列中的第一个数字是根结点 int rootValue = sPreorder[0]; BiTNode* root = new BiTNode(); root->data = rootValue; root->lchild = NULL; root->rchild = NULL; //判断是否只有一个根结点 if(sPreorder == ePreorder) { if(sInorder == eInorder && *sPreorder == *sInorder) return root; else throw std::exception("Invaild input"); } //在中序遍历寻找根结点的值 int* rootInorder = sInorder; while(rootInorder <= eInorder && *rootInorder != rootValue) rootInorder++; if(rootInorder == eInorder && *rootInorder != rootValue) throw std::exception("Invalid input"); //左子树的数量 int leftLength = rootInorder - sInorder; int* leftPreorderEnd = sPreorder + leftLength; if(leftLength > 0) { //构建左子树 root->lchild = constructCore(sPreorder+1,leftPreorderEnd,sInorder,rootInorder - 1); } if(leftLength < ePreorder - sPreorder) { //构建右子树 root->rchild = constructCore(leftPreorderEnd+1,ePreorder,rootInorder+1,eInorder); } return root; } BiTree 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); } /*后序遍历递归函数*/ void postOrderTraverse(BiTree T) { if(T) { postOrderTraverse(T->lchild); postOrderTraverse(T->rchild); cout<<T->data; } } void main () { int preorder[8] = {1, 2, 4, 7, 3, 5, 6, 8}; int inorder[8] = {4, 7, 2, 1, 5, 3, 8, 6}; BiTNode* root = new BiTNode; root = construct(preorder, inorder, 8); printf("后序遍历测试\n"); postOrderTraverse(root); cout<<"\n\n"; }
截图
相关文章推荐
- AVL树-自平衡二叉查找树(Java实现)
- 文件遍历排序函数
- Lua 学习笔记之C API 遍历 Table实现代码
- C#遍历文件夹后上传文件夹中所有文件错误案例分析
- C#中遍历Hashtable的4种方法
- Erlang中遍历取出某个位置的最大值代码
- C++实现图的邻接矩阵存储和广度、深度优先遍历实例分析
- C++实现图的邻接表存储和广度优先遍历实例分析
- C语言二叉树的非递归遍历实例分析
- 使用C语言构建基本的二叉树数据结构
- C++非递归队列实现二叉树的广度优先遍历
- php遍历目录方法小结
- 一个目录遍历函数
- php遍历删除整个目录及文件的方法
- PHP遍历文件夹与文件类及处理类用法实例
- PHP遍历XML文档所有节点的方法
- php中使用key,value,current,next和prev函数遍历数组的方法
- C#使用前序遍历、中序遍历和后序遍历打印二叉树的方法
- 平衡二叉树
- 二叉树