C++中前序遍历和中序遍历重建二叉树例子

已知某二叉树的前序遍历结果和中序遍历结果,假如前序遍历和中序遍历的结果中都不含重复的数字。例如某个二叉树的前序遍历的序列为{1,2,4,7,3,5,6,8}中序遍历序列{4,7,2,1,5,3,8,6}。
通过前序遍历和中序遍历重建二叉树

 struct BinaryTreeNode{
 int m_nValue;
 BinaryTreeNode* m_pLeft;
 BinaryTreeNode* m_pRight;
}
先把三种遍历算法写上:
// 前序遍历
void preOrder(BinaryTreeNode* binaryTreeNode){
 if (binaryTreeNode != NULL)
 {
  printf("%d ",m_pLeft->m_nValue);
  preOrder(binaryTreeNode->m_pLeft);
  preOrder(binaryTreeNode->m_pRight);
 }
}
// 中序遍历
void inOrder(BinaryTreeNode* binaryTreeNode){
 if (binaryTreeNode != NULL)
 {
  inOrder(binaryTreeNode->m_pLeft);
  printf("%d ",binaryTreeNode->m_nValue);
  inOrder(binaryTreeNode->m_pRight);
 }
}
// 后续遍历
void postOrder(BinaryTreeNode* binaryTreeNode){
 if(binaryTreeNode != NULL)
 {
  postOrder(binaryTreeNode->m_pLeft);
  postOrder(binaryTreeNode->m_pRight);
  printf("%d ",m_pLeft->m_nValue);
 }
}

主要还是利用递归,因为二叉树本身就是一种递归的产物,而且又是有序的,所以找到规律递推处理即可。根据上面的图应该可以分析出下面的代码:

BinaryTreeNode* ConstructCore(int* startPreorder,int* endPreorder,int* startInorder,int* endInorder){
 // 前序遍历序列的第一个数字是根节点
 int rootValue = startInorder[0];
 BinaryTreeNode* root = new BinaryTreeNode();
 root->m_nValue = rootValue;
 root->m_pLeft = root->m_pRight = NULL;
 
 // 在中序遍历中找到根节点
 int* rootInorder = startInorder;
 // 如果当前指针对应的指不是根节点,那么指针向后移动一次
 while(rootInorder <= endInorder && *rootInorder != rootValue){
  ++ rootInorder;
 }
 
 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;
}

加以完善,考虑周全些:

BinaryTreeNode* ConstructCore(int* startPreorder,int* endPreorder,int* startInorder,int* endInorder){
 // 前序遍历序列的第一个数字是根节点
 int rootValue = startInorder[0];
 BinaryTreeNode* root = new BinaryTreeNode();
 root->m_nValue = rootValue;
 root->m_pLeft = root->m_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 && *rootInorder != rootValue)
 {
  throw std::exception("Invalid input.");
 }
 
 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;
}

时间: 2024-07-30 02:04:04

C++中前序遍历和中序遍历重建二叉树例子的相关文章

二叉树的创建、前序遍历、中序遍历、后序遍历

// BTree.cpp : Defines the entry point for the console application. /* 作者:成晓旭 时间:2001年7月2日(9:00:00-14:00:00) 内容:完成二叉树的创建.前序遍历.中序遍历.后序遍历 时间:2001年7月2日(14:00:00-16:00:00) 内容:完成二叉树的叶子节点访问,交换左.右孩子 */ #include "stdafx.h" #include "stdlib.h"

UVa 548 Tree:中序遍历&amp;amp;后序遍历&amp;amp;DFS

548 - Tree Time limit: 3.000 seconds http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=104&page=show_problem&problem=489 You are to determine the value of the leaf node in a given binary tree that is the termina

数据结构 排序二叉树(BST) 插入删除查询 中序遍历 销毁(后序遍历)

结构概念如下: 二叉排序树(binary sort tree): 1.也叫做二叉查找树 2.如果他的左子树不为空,则左子树上所有结点的 值均小于他的根结构的值 3.如果他的右子树不为空,则右子树上所有结点的 值均大于他的根结构的值 4.他的左右子树分别为二叉排序树 5.按照二叉树中序遍历其返回结果树有序的 下面就是一颗典型的二叉树,只是是字母,可以将字母换位字母的顺序进行审视,但是它不是平衡二叉树 排序二叉树(BST)的优点在于进行数据查找比较方便,因为他是按照数据来到的顺序进行如上的规则进行的

二叉树前序、中序、后序遍历相互求法

今天来总结下二叉树前序.中序.后序遍历相互求法,即如果知道两个的遍历,如何求第三种遍历方法,比较笨的方法是画出来二叉树,然后根据各种遍历不同的特性来求,也可以编程求出,下面我们分别说明. 首先,我们看看前序.中序.后序遍历的特性:  前序遍历:      1.访问根节点      2.前序遍历左子树      3.前序遍历右子树  中序遍历:      1.中序遍历左子树      2.访问根节点      3.中序遍历右子树  后序遍历:      1.后序遍历左子树      2.后序遍历右

C++中的树、二叉树、二叉树遍历、二叉树前序、中序、后序遍历相互求法

本博文来总结下树.二叉树以及二叉树前序.中序.后序遍历相互求法,即如果知道两个的遍历,如何求第三种遍历方法,比较笨的方法是画出来二叉树,然后根据各种遍历不同的特性来求,也可以编程求出,下面我们分别说明. 1.什么是树?什么是二叉树? 树是一种数据结构,它是由n(n>=1)个有限结点组成一个具有层次关系的集合. 二叉树是指结点的度不超过2的有序树. (结点的度:树中的一个结点拥有的子树数目.) 2.二叉树的前序.中序.后序遍历的特性  二叉树前序遍历特性:   (1).访问根节点  (2).前序遍

UVa 548:Tree 二叉树的重建——中序遍历与后续遍历进行建树

题目链接: http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=104&page=show_problem&problem=489 题目类型: 数据结构, 二叉树 题目大意: 给两个组数字,都是在同一棵二叉树上的,第一组是按中序遍历(inorder)顺序输出的,第二组是按后序遍历(postorder)输出的, 根据这两组数据构建出原来的二叉树,然后计算从根结点到每个叶子结

c语言-二叉树 中序输入,后序遍历,先序确定

问题描述 二叉树 中序输入,后序遍历,先序确定 解决方案 二叉树的非递归先序,中序,后序遍历二叉树的先序.中序.后序遍历二叉树的遍历(先序.中序.后序) 解决方案二: http://blog.csdn.net/zhaojinjia/article/details/9314989

二叉树系列(二):已知中序遍历序列和后序遍历序列,求先序遍历序列

前面已经介绍过三种遍历方法的规则,为了大家看着方便,这里我们在重新介绍一遍:   1.先序遍历   (1)访问根结点:   (2)先序遍历左子树:   (3)先序遍历右子树.   2.中序遍历   (1)中序遍历左子树:   (2)访问根结点:   (3)中序遍历右子树.   3.后序遍历   (1)后序遍历左子树:   (2)后序遍历右子树:   (3)访问根结点.   知道了二叉树的三种遍历规则,只要有中序遍历序列和前后任一种遍历序列,我们就可以求出第三种遍历序列,今天我们研究的是已知中序和

二叉树系列(一):已知先序遍历序列和中序遍历序列,求后序遍历序列

  首先介绍一下三种遍历顺序的操作方法:   1.先序遍历   (1)访问根结点:   (2)先序遍历左子树:   (3)先序遍历右子树.   2.中序遍历   (1)中序遍历左子树:   (2)访问根结点:   (3)中序遍历右子树.   3.后序遍历   (1)后序遍历左子树:   (2)后序遍历右子树:   (3)访问根结点.   知道了二叉树的三种遍历规则,只要有中序遍历序列和前后任一种遍历序列,我们就可以求出第三种遍历序列,今天我们研究的是已知先序和中序遍历序列,求后序遍历序列.