先序中序遍历建立二叉树问题

avecparapluie 2010-05-08 11:31:54
/*根据先序和中序遍历的结果建立一棵二叉树,编译调试都通过了,不能正常运行,哪位大神麻烦看一下*/
#include<stdio.h>
#include<stdlib.h>
typedef int ELemType;

typedef struct BiTreeNode{
ELemType data;
struct BiTreeNode* lchild;
struct BiTreeNode* rchild;
}BiTreeNode,*BiTree;

int main(){
void PreInOrd(ELemType preord[],ELemType inord[],int i,int j,int k,int h,BiTree *t);
void CreateTree(ELemType preord[],ELemType inord[],int n,BiTree root);
BiTree R=NULL;
ELemType preorder[]={0,1,2,4,3,5,7,6,8,9}; /*先序遍历结果,0用于占位*/
ELemType inorder[]={0,4,2,1,5,7,3,8,6,9}; /*中序遍历结果,0用于占位*/
CreateTree(preorder,inorder,9,R);
return 0;
}

void CreateTree(ELemType preord[],ELemType inord[],int n,BiTree root){ /*n二叉树结点数目,建立的二叉树放在root中*/
void PreInOrd(ELemType preord[],ELemType inord[],int i,int j,int k,int h,BiTree *t);
void lastOrder(BiTree head);
if(n<=0) root=NULL;
else PreInOrd(preord,inord,1,n,1,n,&root);
lastOrder(root); /*后序遍历输出*/
}

void PreInOrd(ELemType preord[],ELemType inord[],int i,int j,int k,int h,BiTree *t){/*先序序列从i到j,中序序列从k到h,建立的二叉树放在t中*/
int m;
*t=(BiTree)malloc(sizeof(BiTreeNode));
(*t)->data=preord[i]; /*二叉树的根*/
m=k;
while(inord[m]!=preord[i]) /*在中序序列中定位根*/
m++; //m=3,k=1 m=2,k=1
if(m==k)
(*t)->lchild=NULL;
else
PreInOrd(preord,inord,i+1,i+m-k,k,m-1,&((*t)->lchild)); /*左子树的根结点*/
if(m==h)
(*t)->rchild=NULL;
else
PreInOrd(preord,inord,i+m-k+1,j,m+1,h,&((*t)->lchild));
}

void lastOrder(BiTree head) /*后序遍历*/
{
if(head)
{
lastOrder(head->lchild); /*递归遍历左子树*/
lastOrder(head->rchild); /*递归遍历右子树*/
printf("%d\t",head->data);
}
}
...全文
1772 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
jiayang930828 2013-01-10
  • 打赏
  • 举报
回复
求大神:如果只是用先序建树,那么会不会出错呢???
  • 打赏
  • 举报
回复
发我qq,我帮你调试,但是要给分呀,QQ 1397468184
  • 打赏
  • 举报
回复
二叉树的先序遍历的递归定义如下:
如果二叉树为空,则执行空操作。如果二叉树非空,则执行以下操作:
(1)访问根结点。
(2)先序遍历左子树。
(3)先序遍历右子树。


在二叉树先序的遍历过程中,对每一棵二叉树重复执行以上的递归遍历操作,就可以得到先序序列。例如,在遍历根结点A的左子树{B,D,E,G,H,I}时,根据先序遍历的递归定义,先访问根结点B,然后遍历B的左子树为{D,G},最后遍历B的右子树为{E,H,I}。访问过B之后,开始遍历B的左子树{D,G},在子树{D,G}中,先访问根结点D,因为D没有左子树,所以遍历其右子树,右子树只有一个结点G,所以访问G。B的左子树遍历完毕,按照以上方法遍历B的右子树。最后得到结点A的左子树先序序列:B、D、G、E、H、I。




依据二叉树的先序递归定义,可以得到二叉树的先序递归算法。
void PreOrderTraverse(BiTree T)
/*先序遍历二叉树的递归实现*/
{
if(T) /*如果二叉树不为空*/
{
printf(“%2c”,T->data); /*访问根结点*/
PreOrderTraverse(T->lchild); /*先序遍历左子树*/
PreOrderTraverse(T->rchild); /*先序遍历右子树*/
}
}




二叉树的先序遍历非递归算法实现如下。
void PreOrderTraverse(BiTree T)
/*先序遍历二叉树的非递归实现*/
{
BiTree stack[MaxSize]; /*定义一个栈,用于存放结点的指针*/
int top; /*定义栈顶指针*/
BitNode *p; /*定义一个结点的指针*/
top=0; /*初始化栈*/
p=T;
while(p!=NULL||top>0)
{
while(p!=NULL) /*如果p不空,访问根结点,遍历左子树*/
{
printf(“%2c”,p->data); /*访问根结点*/
stack[top++]=p; /*将p入栈*/
p=p->lchild; /*遍历左子树*/
}
if(top>0) /*如果栈不空*/
{
p=stack[--top]; /*栈顶元素出栈*/
p=p->rchild; /*遍历右子树*/
}
}
}
以上算法是直接利用数组来模拟栈的实现,当然也可以定义一个栈类型实现。如果用第四章的链式栈实现,需要将数据类型改为指向二叉树结点的指针类型。
AAA20090987 2010-05-09
  • 打赏
  • 举报
回复
LZ参加一下这道ACM题吧,是由先序和中序遍历,建立二叉树,再输出后序遍历的

题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=1710

#include <iostream>
using namespace std;

const int SIZE = 1002;
int preOrder[SIZE], inOrder[SIZE];
struct Node
{
int data;
Node *lson;
Node *rson;
};
void CreatTree(Node *&tree, int preNo, int inNo, int len);
void PrintPostOrder(Node *&tree);

int main()
{
int n, i;
Node *root;
while(cin >> n)
{
for(i=0;i<n;i++)
scanf("%d", &preOrder[i]);
for(i=0;i<n;i++)
scanf("%d", &inOrder[i]);
CreatTree(root, 0, 0, n);
PrintPostOrder(root);
printf("\n");
}
return 0;
}

void CreatTree(Node *&tree, int preNo, int inNo, int len)
{
int i;
if(len <= 0)
{
tree = NULL;
return;
}
tree = new Node;
tree->data = preOrder[preNo];
for(i=0;i<len;i++)
if(preOrder[preNo] == inOrder[inNo+i])
break;
CreatTree(tree->lson, preNo+1, inNo, i);
CreatTree(tree->rson, preNo+i+1, inNo+i+1, len-i-1);
}

void PrintPostOrder(Node *&tree)
{
if(NULL == tree)
return;
PrintPostOrder(tree->lson);
PrintPostOrder(tree->rson);
printf("%d", tree->data);
if(tree->data != preOrder[0])
printf(" ");
}
avecparapluie 2010-05-09
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 crcr 的回复:]

二叉树的先序遍历的递归定义如下:
如果二叉树为空,则执行空操作。如果二叉树非空,则执行以下操作:
(1)访问根结点。
(2)先序遍历左子树。
(3)先序遍历右子树。


在二叉树先序的遍历过程中,对每一棵二叉树重复执行以上的递归遍历操作,就可以得到先序序列。例如,在遍历根结点A的左子树{B,D,E,G,H,I}时,根据先序遍历的递归定义,先访问根结点B,然后遍历B的左子树为{D……
[/Quote]重点不是如何遍历,答非所问。。。
z569362161 2010-05-09
  • 打赏
  • 举报
回复
我是来看厚脸皮的,不要分。
huanmie_09 2010-05-09
  • 打赏
  • 举报
回复
来接个分,呵呵.

/*求助:根据先序和中序遍历的结果建立一棵二叉树,编译调试都通过了,但不能正常运行,大神麻烦帮我看一下*/

#include<stdio.h>
#include<stdlib.h>

typedef int ELemType;

typedef struct BiTreeNode{
ELemType data;
struct BiTreeNode* lchild;
struct BiTreeNode* rchild;
} BiTreeNode, *BiTree;

void CreateTree(ELemType preord[],ELemType inord[],int n,BiTree *root);
void PreInOrd(ELemType preord[],ELemType inord[],int i,int j,int k,int h,BiTree *t);
void lastOrder(BiTree head);

int main()
{
//void PreInOrd(ELemType preord[],ELemType inord[],int i,int j,int k,int h,BiTree *t);
//void CreateTree(ELemType preord[],ELemType inord[],int n,BiTree root);
BiTree R=NULL;
ELemType preorder[]={0,1,2,4,3,5,7,6,8,9}; /*先序遍历结果,0用于占位*/
ELemType inorder[]={0,4,2,1,5,7,3,8,6,9}; /*中序遍历结果,0用于占位*/

/*
1,2,4,3,5,7,6,8,9
4,2,1,5,7,3,8,6,9

1
2 3
4 5 6
7 8 9
后序遍历:
4 2 7 5 8 9 6 3 1
*/

CreateTree(preorder,inorder,9,&R);
return 0;
}

//void CreateTree(ELemType preord[],ELemType inord[],int n,BiTree root)
void CreateTree(ELemType preord[],ELemType inord[],int n,BiTree *root)
{ /*n二叉树结点数目,建立的二叉树放在root中*/
if(n<=0) {
(*root)=NULL;
}
else {
//PreInOrd(preord,inord,1,n,1,n,&root);
PreInOrd(preord,inord,1,n,1,n,root);
}
lastOrder(*root); /*后序遍历输出*/
}

void PreInOrd(ELemType preord[],ELemType inord[],int i,int j,int k,int h,BiTree *t)
{/*先序序列从i到j,中序序列从k到h,建立的二叉树放在t中*/
int m;
*t=(BiTree)malloc(sizeof(BiTreeNode));
//(*t)->data=preord; /*二叉树的根*/
(*t)->data=preord[i];
m=k;
//while(inord[m]!=preord) { /*在中序序列中定位根*/
while(m <=h&&inord[m]!=preord[i]) {
m++; //m=3,k=1 m=2,k=1
}
if(m==k) {
(*t)->lchild=NULL;
}
else {
PreInOrd(preord,inord,i+1,i+m-k,k,m-1,&((*t)->lchild));
}
if(m==h) {
(*t)->rchild=NULL;
}
else {
PreInOrd(preord,inord,i+m-k+1,j,m+1,h,&((*t)->rchild)); //这里是右子树
}
}

void lastOrder(BiTree head) /*后序遍历*/
{
if(head)
{
lastOrder(head->lchild); /*递归遍历左子树*/
lastOrder(head->rchild); /*递归遍历右子树*/
printf("%d\t",head->data);
}
}

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧