已知二叉树先序遍历,中序遍历创建二叉树并输出后序遍历
2012-10-07 17:56
423 查看
QQ:1423173783 邮箱1423173783@qq.com
下面两两段代码是别人贴到搜搜问问中的东西,我觉得问问题的人的代码的质量总体要比回答的人的好。我对他俩的代码稍作了修改,见第三,四段代码,修改处以别的颜色标明。
#include <iostream>
using namespace std;
#define FALSE 1
#define OK 0
typedef struct BiTNode
{
char data;
struct BiTNode *lchild,*rchild; /*左右孩子指针*/
} BiTNode ,*BiTree;
void CreateBiTree(BiTree &T,char *p1,char *p2,int n)
{
int k;
char *root;
if(n<=0)
{
root=NULL;
return ;
}
T=(BiTree)malloc(sizeof(BiTNode));
T->data=*p1;
for(root=p2;root<p2+n;root++)
{
if(*root=*p1)
break;
}
k=root-p2;
CreateBiTree(T->lchild,p1+1,p2,k);
CreateBiTree(T->rchild,p1+k+1,root+1,n-k-1);
};
void PostOrderTraverse( BiTree T)
{
if(T!=NULL)
{
PostOrderTraverse(T->lchild);
PostOrderTraverse(T->rchild);
cout<<""<<T->data;
}
};
void main()
{
BiTree T;
char s1[50],s2[50];
cout<<"请输入先序序列:"<<endl;
cin.getline(s1,49);
cout<<"请输入中序序列:"<<endl;
cin.getline(s2,49);
CreateBiTree(T,s1,s2,strlen(s1));
cout<<"该树的后序序列为:"<<endl;
PostOrderTraverse(T);
}
程序如上,调试结果为q.exe 中的 0x011c1627 处最可能的异常: 0xC0000005: 读取位置 0xcdcdcdd1 时发生访问冲突
q.exe 中的 0x011c1627 处有未经处理的异常: 0xC0000005: 读取位置 0xcdcdcdd1 时发生访问冲突
求高手指点TT
你的错误是你树的左右子树都没有初始化就调用,所以才会访问异常。
再一个更严重的错误就是你的CreateBiTree的逻辑就有问题,都给你改正了并添加了注释
记得前面加上头文件 #include <string>
void CreateBiTree(BiTree &T,char *p1,char *p2,int n)
{
int k;
char *left,*right;
int i;
if(n<=0)
{
return ;
}
T=(BiTree)malloc(sizeof(BiTNode));
T->lchild=NULL; //malloc以后不会把指针指向NULL,需要手动指向。
T->rchild=NULL;
T->data=p1[0]; //*p1是个字符串,不是char,要这么写
for(i=0;i<n;i++)
{
if(p2[i]==p1[0])//你这里是想判断出p2中根的位置吧,应该这样
break;
}
//这里i是p2字符串中根的位置,那么p2[0]到p2[i-1]就是左子树,i+1到n就是右子树
left=(char*)malloc(i+1);//多分配一个,写入终止符
strncpy(left,p2,i);
left[i]='\0';
//同理,分配右子树
right=p2+i+1;//right指向右子树
if(strlen(left)>0) //这里要判断是否还有左子树,否则会无限递归
CreateBiTree(T->lchild,p1+1,left,strlen(p1+1));
if(strlen(right)>0)//同理
CreateBiTree(T->rchild,p1+i+1,right,strlen(p1+i+1));
};
void PostOrderTraverse( BiTree T)
{
if(T!=NULL)
{
if(T->lchild)//要保证子树非空
PostOrderTraverse(T->lchild);
if(T->rchild)
PostOrderTraverse(T->rchild);
cout<<""<<T->data;
}
};
#include <iostream>
#include<cstdlib>
using namespace std;
typedef struct BiTNode
{
char data;
struct BiTNode *lchild,*rchild; /*左右孩子指针*/
} BiTNode ,*BiTree;
void CreateBiTree(BiTree &T,char *p1,char *p2,int n)
{
int k;
char *root;
if(n<=0)
{
T=NULL;
return ;
}
T=(BiTree)malloc(sizeof(BiTNode));
T->lchild=NULL;
T->rchild=NULL;
T->data=*p1;
for(root=p2;root<p2+n;root++)
{
if(*root==*p1)
break;
}
k=root-p2;
CreateBiTree(T->lchild,p1+1,p2,k);
CreateBiTree(T->rchild,p1+k+1,root+1,n-k-1);
};
void PostOrderTraverse( BiTree T)
{
if(T!=NULL)
{
PostOrderTraverse(T->lchild);
PostOrderTraverse(T->rchild);
cout<<""<<T->data;
}
};
void main()
{
BiTree T;
char s1[50],s2[50];
cout<<"请输入先序序列:"<<endl;
cin.getline(s1,49);
cout<<"请输入中序序列:"<<endl;
cin.getline(s2,49);
CreateBiTree(T,s1,s2,strlen(s1));
cout<<"该树的后序序列为:"<<endl;
PostOrderTraverse(T);
system("pause");
}
#include <iostream>
#include<cstdlib>
#include<string>
using namespace std;
typedef struct BiTNode
{
char data;
struct BiTNode *lchild,*rchild; /*左右孩子指针*/
} BiTNode ,*BiTree;
void CreateBiTree(BiTree &T,char *p1,char *p2,int n)
{
int k;
char *left,*right;
int i;
if(n<=0)
{
return ;
}
T=(BiTree)malloc(sizeof(BiTNode));
T->lchild=NULL; //malloc以后不会把指针指向NULL,需要手动指向。
T->rchild=NULL;
T->data=p1[0]; //*p1是个字符串,不是char,要这么写
for(i=0;i<n;i++)
{
if(p2[i]==p1[0])//你这里是想判断出p2中根的位置吧,应该这样
break;
}
//这里i是p2字符串中根的位置,那么p2[0]到p2[i-1]就是左子树,i+1到n就是右子树
left=(char*)malloc(i+1);//多分配一个,写入终止符
strncpy(left,p2,i);
left[i]='\0';
//同理,分配右子树
right=p2+i+1;//right指向右子树
CreateBiTree(T->lchild,p1+1,left,strlen(left));
CreateBiTree(T->rchild,p1+i+1,right,strlen(right));
};
void PostOrderTraverse( BiTree T)
{
if(T!=NULL)
{
PostOrderTraverse(T->lchild);
PostOrderTraverse(T->rchild);
cout<<""<<T->data;
}
};
void main()
{
BiTree T;
char s1[50],s2[50];
cout<<"请输入先序序列:"<<endl;
cin.getline(s1,49);
cout<<"请输入中序序列:"<<endl;
cin.getline(s2,49);
CreateBiTree(T,s1,s2,strlen(s1));
cout<<"该树的后序序列为:"<<endl;
PostOrderTraverse(T);
system("pause");
}
下面两两段代码是别人贴到搜搜问问中的东西,我觉得问问题的人的代码的质量总体要比回答的人的好。我对他俩的代码稍作了修改,见第三,四段代码,修改处以别的颜色标明。
#include <iostream>
using namespace std;
#define FALSE 1
#define OK 0
typedef struct BiTNode
{
char data;
struct BiTNode *lchild,*rchild; /*左右孩子指针*/
} BiTNode ,*BiTree;
void CreateBiTree(BiTree &T,char *p1,char *p2,int n)
{
int k;
char *root;
if(n<=0)
{
root=NULL;
return ;
}
T=(BiTree)malloc(sizeof(BiTNode));
T->data=*p1;
for(root=p2;root<p2+n;root++)
{
if(*root=*p1)
break;
}
k=root-p2;
CreateBiTree(T->lchild,p1+1,p2,k);
CreateBiTree(T->rchild,p1+k+1,root+1,n-k-1);
};
void PostOrderTraverse( BiTree T)
{
if(T!=NULL)
{
PostOrderTraverse(T->lchild);
PostOrderTraverse(T->rchild);
cout<<""<<T->data;
}
};
void main()
{
BiTree T;
char s1[50],s2[50];
cout<<"请输入先序序列:"<<endl;
cin.getline(s1,49);
cout<<"请输入中序序列:"<<endl;
cin.getline(s2,49);
CreateBiTree(T,s1,s2,strlen(s1));
cout<<"该树的后序序列为:"<<endl;
PostOrderTraverse(T);
}
程序如上,调试结果为q.exe 中的 0x011c1627 处最可能的异常: 0xC0000005: 读取位置 0xcdcdcdd1 时发生访问冲突
q.exe 中的 0x011c1627 处有未经处理的异常: 0xC0000005: 读取位置 0xcdcdcdd1 时发生访问冲突
求高手指点TT
推荐答案
你的错误是你树的左右子树都没有初始化就调用,所以才会访问异常。再一个更严重的错误就是你的CreateBiTree的逻辑就有问题,都给你改正了并添加了注释
记得前面加上头文件 #include <string>
void CreateBiTree(BiTree &T,char *p1,char *p2,int n)
{
int k;
char *left,*right;
int i;
if(n<=0)
{
return ;
}
T=(BiTree)malloc(sizeof(BiTNode));
T->lchild=NULL; //malloc以后不会把指针指向NULL,需要手动指向。
T->rchild=NULL;
T->data=p1[0]; //*p1是个字符串,不是char,要这么写
for(i=0;i<n;i++)
{
if(p2[i]==p1[0])//你这里是想判断出p2中根的位置吧,应该这样
break;
}
//这里i是p2字符串中根的位置,那么p2[0]到p2[i-1]就是左子树,i+1到n就是右子树
left=(char*)malloc(i+1);//多分配一个,写入终止符
strncpy(left,p2,i);
left[i]='\0';
//同理,分配右子树
right=p2+i+1;//right指向右子树
if(strlen(left)>0) //这里要判断是否还有左子树,否则会无限递归
CreateBiTree(T->lchild,p1+1,left,strlen(p1+1));
if(strlen(right)>0)//同理
CreateBiTree(T->rchild,p1+i+1,right,strlen(p1+i+1));
};
void PostOrderTraverse( BiTree T)
{
if(T!=NULL)
{
if(T->lchild)//要保证子树非空
PostOrderTraverse(T->lchild);
if(T->rchild)
PostOrderTraverse(T->rchild);
cout<<""<<T->data;
}
};
#include <iostream>
#include<cstdlib>
using namespace std;
typedef struct BiTNode
{
char data;
struct BiTNode *lchild,*rchild; /*左右孩子指针*/
} BiTNode ,*BiTree;
void CreateBiTree(BiTree &T,char *p1,char *p2,int n)
{
int k;
char *root;
if(n<=0)
{
T=NULL;
return ;
}
T=(BiTree)malloc(sizeof(BiTNode));
T->lchild=NULL;
T->rchild=NULL;
T->data=*p1;
for(root=p2;root<p2+n;root++)
{
if(*root==*p1)
break;
}
k=root-p2;
CreateBiTree(T->lchild,p1+1,p2,k);
CreateBiTree(T->rchild,p1+k+1,root+1,n-k-1);
};
void PostOrderTraverse( BiTree T)
{
if(T!=NULL)
{
PostOrderTraverse(T->lchild);
PostOrderTraverse(T->rchild);
cout<<""<<T->data;
}
};
void main()
{
BiTree T;
char s1[50],s2[50];
cout<<"请输入先序序列:"<<endl;
cin.getline(s1,49);
cout<<"请输入中序序列:"<<endl;
cin.getline(s2,49);
CreateBiTree(T,s1,s2,strlen(s1));
cout<<"该树的后序序列为:"<<endl;
PostOrderTraverse(T);
system("pause");
}
#include <iostream>
#include<cstdlib>
#include<string>
using namespace std;
typedef struct BiTNode
{
char data;
struct BiTNode *lchild,*rchild; /*左右孩子指针*/
} BiTNode ,*BiTree;
void CreateBiTree(BiTree &T,char *p1,char *p2,int n)
{
int k;
char *left,*right;
int i;
if(n<=0)
{
return ;
}
T=(BiTree)malloc(sizeof(BiTNode));
T->lchild=NULL; //malloc以后不会把指针指向NULL,需要手动指向。
T->rchild=NULL;
T->data=p1[0]; //*p1是个字符串,不是char,要这么写
for(i=0;i<n;i++)
{
if(p2[i]==p1[0])//你这里是想判断出p2中根的位置吧,应该这样
break;
}
//这里i是p2字符串中根的位置,那么p2[0]到p2[i-1]就是左子树,i+1到n就是右子树
left=(char*)malloc(i+1);//多分配一个,写入终止符
strncpy(left,p2,i);
left[i]='\0';
//同理,分配右子树
right=p2+i+1;//right指向右子树
CreateBiTree(T->lchild,p1+1,left,strlen(left));
CreateBiTree(T->rchild,p1+i+1,right,strlen(right));
};
void PostOrderTraverse( BiTree T)
{
if(T!=NULL)
{
PostOrderTraverse(T->lchild);
PostOrderTraverse(T->rchild);
cout<<""<<T->data;
}
};
void main()
{
BiTree T;
char s1[50],s2[50];
cout<<"请输入先序序列:"<<endl;
cin.getline(s1,49);
cout<<"请输入中序序列:"<<endl;
cin.getline(s2,49);
CreateBiTree(T,s1,s2,strlen(s1));
cout<<"该树的后序序列为:"<<endl;
PostOrderTraverse(T);
system("pause");
}
相关文章推荐
- 已知二叉树的先序遍历序列和中序遍历序列,输出该二叉树的后序遍历序列
- 二叉树创建、先序遍历、中序遍历、后序遍历、树深度
- 已知二叉树的先序遍历序列和中序遍历序列,输出该二叉树的后序遍历序列
- C++ 二叉树实现 创建,先序遍历,中序遍历,后序遍历
- 根据中序遍历和先序遍历,后序遍历创建二叉树。
- 已知二叉树的先序遍历序列和中序遍历序列,输出该二叉树的后序遍历序列
- 二叉树的创建,先序遍历,中序遍历,后序遍历
- 已知二叉树先序遍历中序遍历求后序遍历
- 创建一个二叉树(先序遍历、中序遍历、后序遍历)
- 一个关于二叉树的创建、先序遍历、中序遍历、后序遍历、求叶子节点的完整函数的c语言完整程序。
- 已知二叉树的先序遍历序列和中序遍历序列,输出该二叉树的后序遍历序列
- 数据结构--二叉树的创建、先序遍历、中序遍历、后序遍历、深度、叶子结点数
- 已知一颗二叉树,如果先序遍历的节点顺序是:ADCEFGHB,中序遍历是,CDFEGHAB,则后序遍历的结果为
- 二叉树的创建(先序创建的)及先序遍历 中序遍历 后序遍历的递归和非递归实现
- 已知一棵二叉树的中序遍历和后序遍历,求二叉树的先序遍历
- 已知二叉树的先序遍历序列和中序遍历序列,输出该二叉树的后序遍历序列
- 已知一棵二叉树的中序遍历和后序遍历,求二叉树的先序遍历
- 先序顺序输入结点值创建二叉树,并按先序,中序和后序遍历输出
- c++实现二叉树的先序遍历,中序遍历,后序遍历(递归方法)及运行实例结果
- 已知二叉树的前序遍历中序遍历,求后序遍历