根据先序遍历中序遍历重建二叉树

根据先序遍历和中序遍历的特点,我们想到了采用递归的方法来实现。

思路:1) 代码的容错性检查,比如:先序遍历和中序遍历长度应相等

2)
先保存先序遍历的第一个点,这个点为结点,接下来循环中序遍历,直到midOrd[index]=该结点,那么接下来就可以采用递归,分别对结点左边和右边的序列采用相同的方法。

3) 直到中序遍历中的序列中只含一个点,整个过程结束。

下面是我写的代码,一直显示错误,不知道什么原因。


// 先序中序重建二叉树.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <iostream>
using namespace std;

typedef int type;
typedef struct bitNode
{
type data;
bitNode *leftTree;
bitNode *rightTree;

}bitTree,*BitTree;

void rebuildTree(bitTree**T,type pre_order[],int pre_left,int pre_right,type mid_order[],int mid_left,int mid_right)
{
int index;
int length; //每个序列的长度
//1.容错性判断
if((pre_right-pre_left)!=(mid_right-mid_left))
{
cout<<"错误1!"<<endl;
return ;
}
//2.每次新建一个节点,将先序遍历序列的第一个元素保存下来
(*T)=new bitTree;
(*T)->data=pre_order[pre_left];
(*T)->leftTree=NULL;
(*T)->rightTree=NULL;

//3.遍历中序序列,如果找到与上一节点元素相同,则退出循环。此时就可以对其构建二叉树
for (index=mid_left;index<=mid_right;index++)
{
if (mid_order[index]==(*T)->data)
break;
}

if ((index-1)>mid_right)
{
cout<<"错误2!"<<endl;
return ;
}

//4.递归调用,分别对中序序列的左右两边进行递归。注意递归条件。如果只有一个元素就不递归。
//中序遍历序列中的左边序列
if((index-mid_left)>0) //必须保证中序遍历序列中左边或者右边有元素的时候才会去递归调用
{
length=index-pre_left;
rebuildTree(&((*T)->leftTree),pre_order,pre_left+1,pre_left+1+length-1,mid_order,mid_left,mid_left+length-1);
}
//中序遍历序列中右边的序列
if ((mid_right-index)>0)
{
length=mid_right-index;
rebuildTree(&((*T)->rightTree),pre_order,index+1,index+1+length-1,mid_order,index+1,index+1+length-1);
}

}

void postVisit(bitTree *tree)
{
if (tree)
{
postVisit(tree->leftTree);
postVisit(tree->rightTree);
cout<<tree->data<<endl;
}

}

int main(int argc, char* argv[])
{
type preOrder[]={1,2,4,5,3,6};
type midOrder[]={4,2,5,1,6,3};
bitTree *Tree;
rebuildTree(&Tree,preOrder,0,5,midOrder,0,5);
postVisit(Tree);
return 0;
}

可以得到答案的程序:


// 先序中序重建二叉树.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <iostream>
using namespace std;

typedef int type;
typedef struct bitNode
{
type data;
bitNode *leftTree;
bitNode *rightTree;

}bitTree,*BitTree;

BitTree rebuildTree(type pre_order[],int pre_left,int pre_right,type mid_order[],int mid_left,int mid_right)
{
int index;
int length; //每个序列的长度
//1.容错性判断
if((pre_right-pre_left)!=(mid_right-mid_left)||(pre_left>pre_right))
return NULL;

//2.每次新建一个节点,将先序遍历序列的第一个元素保存下来

BitTree T=new bitTree;
T->data=pre_order[pre_left];
T->leftTree=NULL;
T->rightTree=NULL;

//3.遍历中序序列,如果找到与上一节点元素相同,则退出循环。此时就可以对其构建二叉树
for (index=mid_left;index<=mid_right;index++)
{
if (mid_order[index]==T->data)
break;
}

if (index>mid_right)
return NULL;

//4.递归调用,分别对中序序列的左右两边进行递归。注意递归条件。如果只有一个元素就不递归。
//中序遍历序列中的左边序列
if((index-mid_left)>0) //必须保证中序遍历序列中左边或者右边有元素的时候才会去递归调用
{
length=index-pre_left;
T->leftTree= rebuildTree(pre_order,pre_left+1,pre_left+1+length-1,mid_order,mid_left,mid_left+length-1);
}
//中序遍历序列中右边的序列
if ((mid_right-index)>0)
{
length=mid_right-index;
T->rightTree= rebuildTree(pre_order,pre_right-length+1,pre_right,mid_order,mid_right-length+1,mid_right);
}
return T; //要返回头结点,所以注意别掉了。

}

void postVisit(bitTree *tree)
{
if (tree)
{
postVisit(tree->leftTree);
postVisit(tree->rightTree);
cout<<tree->data<<" ";
}

}

int main(int argc, char* argv[])
{
type preOrder[]={1,2,4,5,3,6};
type midOrder[]={4,2,5,1,6,3};
BitTree Tree;
Tree=rebuildTree(preOrder,0,5,midOrder,0,5);
postVisit(Tree);
return 0;
}

根据先序遍历中序遍历重建二叉树,布布扣,bubuko.com

时间: 2025-01-03 20:58:38

根据先序遍历中序遍历重建二叉树的相关文章

前序+中序 = 二叉树(先序、中序、后序、层次遍历)

内心OS:我靠啊!!!我就是偷了一下懒!!!把先序遍历的代码COPY了两份,改成了中序和后序遍历.万万没想到啊!我忘了修改函数中递归函数的名字!!!找这个BUG花了我三个小时~~我哭啊~~,我还以为我的知识体系坍塌了呢?!!~ 总结,这是一道模板题,要先记住大体流程,然后反复练习. 输入格式: 第一行给出结点个数 N(1<=N<= 50) 第二行给出先序序列,共N个整数 第三行给出后序序列,共N个整数 输出格式: 第一行给出先序遍历结果: 第二行给出中序遍历结果: 第三行给出后续遍历结果: 第

二叉树高度,以及栈实现二叉树的先序,中序,后序遍历的非递归操作

求解二叉树的高度 树是递归定义的,所以用递归算法去求一棵二叉树的高度很方便. #include <iostream> #include <cstdio> using namespace std; struct Node { char data; Node *lchild; Node *rchild; }; void High(Node *T, int &h) { if (T == NULL) h = 0; else { int left_h; High(T->lchi

给出二叉树的先序和中序遍历,给出后序遍历

实现一个功能: 输入:一颗二叉树的先序和中序遍历 输出:后续遍历 思想: 先序遍历中,第一个元素是树根 在中序遍历中找到树根,左边的是左子树 右边的是右子树 1 def fromFMtoL( mid ): 2 global las #全局后序遍历 3 global fir #先序遍历 4 5 root = fir[0] #取出当前树根 6 7 fir = fir[1:] #取出树根后 先序遍历把根拿出来 下面一个元素做树根 8 root_po = mid.find( root ) #在中序遍历当

给定二叉树先序、中序遍历序列,求后序遍历

给定一个二叉树的前序遍历和中序遍历的序列,输出对应这个二叉树的后续遍历序列. 输入描述: 输入为一行. 两个字符串,分别表示二叉树的前序遍历和中序遍历结果,用空格分隔.保证数据合法 输出描述: 对应输出后序遍历序列 示例1 输入 ABDEC DBEAC 输出 DEBCA思路:先根据先序.中序序列建立二叉树,然后后序遍历 import java.util.Scanner; import javax.print.attribute.standard.PresentationDirection; cl

[LeetCode] Construct Binary Tree from Preorder and Inorder Traversal 由先序和中序遍历建立二叉树

Given preorder and inorder traversal of a tree, construct the binary tree. Note:You may assume that duplicates do not exist in the tree. 这道题要求用先序和中序遍历来建立二叉树,跟之前那道Construct Binary Tree from Inorder and Postorder Traversal 由中序和后序遍历建立二叉树原理基本相同,针对这道题,由于先

C语言非递归实现二叉树的先序、中序、后序、层序遍历

C语言非递归实现二叉树的先序.中序.后序.层序遍历代码如下: 1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <stack> 4 #include <queue> 5 using namespace std; 6 7 //*****二叉树的二叉链表存储表示*****// 8 typedef struct BiNode 9 { 10 char data; 11 struct BiNode *lchil

非递归遍历二叉树【层次遍历,先序、中序、后序遍历】

一.层次遍历:借助队列实现 1 void LevelOrderTraversal(BiTree root) 2 { 3 BiTree e = root;//从根节点开始 4 Queue *q; 5 InitQueue(q); 6 7 if(e)//若根结点非空,则入队列 8 { 9 EnQueue(q,e); 10 } 11 12 while(!QueueEmpty(q)) 13 { 14 DelQueue(q,e); 15 Visit(e); 16 if(e->leftChild)//左孩子不

已知二叉树的先序,中序遍历,求后续遍历

//已知二叉树的先序,中序遍历,求后续遍历 struct TreeNode { char elem; struct TreeNode* left; struct TreeNode* right; }; TreeNode* BinaryTree(char* inorder,char* preorder,int length) { if(length == 0) return NULL; TreeNode* node = new TreeNode; node->elem = *preorder; i

二叉树先序、中序、后序遍历的递归算法和非递归算法

先序遍历:若二叉树为空,则空操作:否则访问根节点:先序遍历左子树:先序遍历右子树. 中序遍历:若二叉树为空,则空操作:否则中序遍历左子树:访问根节点:中序遍历右子树. 后序遍历:若二叉树为空,则空操作:否则后序遍历左子树:后序遍历右子树:访问根节点. 二叉链表:链表中的结点包含三个域:数据域和左右指针域. 三叉链表:在二叉链表的基础上增加指向双亲结点的指针域. 以下代码均使用二叉链表. //二叉树的二叉链表存储表示 typedef char TElemType; typedef struct B