题目四:求二叉树上结点的路径
设计要求:在采用链式存储结构存储的二叉树上,以bt 指
向根结点,p 指向任一给定的结点,编程实现求出从根结点
到给定结点之间的路径。
菜单内容:
1. 建立二叉树存储结构
2. 求二叉树的前序遍历
3. 求二叉树的中序遍历
4. 求二叉树的后续遍历
5. 求指定结点的路径
6. 退出系统
请选择:1 – 6:
提示:
【采用非递归遍历的方法】
1. 二叉树的建立
2. 求指定结点的路径
3. 二叉树的前、中、后序非递归遍历算法
4. 查找函数
使用结构体:树和栈 栈用来实现非递归以及路径
typedef struct Tree {
char data;
int run=0;//在后序遍历的非递归中使用 表示这个节点是否被访问过
struct Tree *l,*r;
} Tree,*BiTree;
//用栈来存储指针
typedef struct Stack {
Tree **top;
Tree **base;
int stacksize;//
} Stack;
首先,输入按照先序遍历树的字符串,其中若结点为空,则用'#'表示:
递归方法创建:
void CreateTree2(BiTree &T) {
char c;
cin>>c;
if(c=='#')
T=NULL;
else {
InitTree(T,c);
CreateTree2(T->l);
CreateTree2(T->r);
}
}
非递归方法(代码可能有问题 当时注释掉了 略过略过):
int CreateTree1(BiTree &bt) {
Stack ss;
InitStack(ss);
cout << "按照先序输入树,用'#'表示空:" << endl;
char input[100];
BiTree p=bt;
int i=0;
gets(input);
int n=strlen(input);
for(i=0; il;
} else {
InitTree(p,input[i]);
if(isempty(ss)||i==n-1) {
p=bt;
return 0;
}
else
bt=pop(ss,p);
if(p->l&&(p->r==NULL)) {
p=p->r;
}
else {
while(p->l&&p->r) {
if(isempty(ss))
return 0;
else
bt=pop(ss,p);
}
p=p->r;
}
}
}
}
先序和中序遍历的非递归方式:
先序:
1.先输出该结点的值,然后把该节点压入栈中,然后沿着该节点的左子树继续,直到该结点为空;
2.此时如果栈不为空,则弹出栈顶元素,并访问其右子树,执行1,否则结束。
中序:
和先序类似,唯一不同的是输出该结点的时机是在出栈时,而不是在最开始。
void First(BiTree T) {
Stack sf;
InitStack(sf);
Tree *p=T;
while(p||!isempty(sf)) {
while(p) {
cout<data<<' ';
push(sf,p);
p=p->l;
}
if(!isempty(sf)) {
p=pop(sf,p);
p=p->r;
}
}
cout<l;
}
if (!isempty(sm)) {
p=pop(sm,p);
cout <data<<' ';
p = p->r;
}
}
cout<
后序:
后序输出结点的值是要判断其左右结点(如果存在)是否都被访问过才可以。
首先类似中序的方法先沿着左子树走并压入栈中,当结点为空时,如果栈不空,则弹出栈顶元素,如果这个元素的右子树存在并且没有被访问过的话,那么把当前结点压入栈中,并访问其右子树,执行最开始的沿着左子树的过程,如果右子树不存在或者右子树已经被访问,那么输出该结点的值,并值该节点的访问为1.如果栈空,结束。
void Last(BiTree T) {
Stack sl;
InitStack(sl);
Tree *p=T;
while (p||!isempty(sl)) {
while(p&&p->run==0) {
push(sl,p);
p = p->l;
}
if (!isempty(sl)) {
p=pop(sl,p);
// cout<<2;
if(p->r&&p->r->run==0) {
push(sl,p);
p = p->r;
// cout<<3;
}
else {
cout <data<<' ';//
p->run=1;
if(isempty(sl)) {
cout<
根节点到任意结点的路径:
有点类似于分治法的思想,如果这个点存在这个树中(值唯一),那么必定满足以下条件的唯一一个:
1.该结点在根节点被找到
2.该节点在根节点的左子树被找到
3.该节点在根节点的右子树被找到
如果都不满足,则不在这个树内。
利用这个思想,判断树是否满足三个条件中的一个,如果满足,则把根压入栈中,最后依次弹出,即为路径。
bool Find(BiTree T,char c){
if(T==NULL)
return 0;
if(T->data==c||Find(T->l,c)||Find(T->r,c)){
push(sq,T);
count++;
return 1;
}
return 0;
}
void jiedian(BiTree T){
InitStack(sq);
char d1;
cout<<"请输入指定的结点:";
cin>>d1;
Find(T,d1);
if(isempty(sq)){
cout<<"cannot find.";
}
while(!isempty(sq)){
BiTree p=pop(sq,p);
cout<data;
if(count!=1)
cout<<"->";
count--;
}
cout<
完整代码:
#include
#include
#include
#include
#define SIZE 100
#define incre 10
using namespace std;
typedef struct Tree {
char data;
int run=0;
struct Tree *l,*r;
} Tree,*BiTree;
//用栈来存储指针
typedef struct Stack {
Tree **top;
Tree **base;
int stacksize;//
} Stack;
int isempty(Stack s) {
if(s.top==s.base)
return 1;
else
return 0;
}
void InitStack(Stack &s) {
s.base=(Tree **)malloc(SIZE*sizeof(Tree));
s.top=s.base;
s.stacksize=SIZE;
}
void push(Stack &s,Tree *p) {
*s.top++=p;
}
Tree *pop(Stack &s,Tree *p) {
if(s.top==s.base)
exit(-1);
p=*--s.top;
return p;
}
void InitTree(BiTree &T,char c) {
T=(BiTree)malloc(sizeof(Tree));
T->data=c;
T->l=NULL;
T->r=NULL;
}
void First(BiTree T) {
Stack sf;
InitStack(sf);
Tree *p=T;
while(p||!isempty(sf)) {
while(p) {
cout<data<<' ';
push(sf,p);
p=p->l;
}
if(!isempty(sf)) {
p=pop(sf,p);
p=p->r;
}
}
cout<l;
}
if (!isempty(sm)) {
p=pop(sm,p);
cout <data<<' ';
p = p->r;
}
}
cout<run==0) {
push(sl,p);
p = p->l;
}
if (!isempty(sl)) {
p=pop(sl,p);
// cout<<2;
if(p->r&&p->r->run==0) {
push(sl,p);
p = p->r;
// cout<<3;
}
else {
cout <data<<' ';//
p->run=1;
if(isempty(sl)) {
cout<l;
} else {
InitTree(p,input[i]);
if(isempty(ss)||i==n-1) {
p=bt;
return 0;
}
else
bt=pop(ss,p);
if(p->l&&(p->r==NULL)) {
p=p->r;
}
else {
while(p->l&&p->r) {
if(isempty(ss))
return 0;
else
bt=pop(ss,p);
}
p=p->r;
}
}
}
}
void CreateTree2(BiTree &T) {
char c;
cin>>c;
if(c=='#')
T=NULL;
else {
InitTree(T,c);
CreateTree2(T->l);
CreateTree2(T->r);
}
}
Stack sq;
int count;
bool Find(BiTree T,char c){
if(T==NULL)
return 0;
if(T->data==c||Find(T->l,c)||Find(T->r,c)){
push(sq,T);
count++;
return 1;
}
return 0;
}
void jiedian(BiTree T){
InitStack(sq);
char d1;
cout<<"请输入指定的结点:";
cin>>d1;
Find(T,d1);
if(isempty(sq)){
cout<<"cannot find.";
}
while(!isempty(sq)){
BiTree p=pop(sq,p);
cout<data;
if(count!=1)
cout<<"->";
count--;
}
cout<