栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

求二叉树中从根结点到叶子结点的路径

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

求二叉树中从根结点到叶子结点的路径

#include "tree.cpp"		//包含二叉树的基本运算 
typedef char ElemType;



//采用先序遍历方法输出所有从叶子结点到根结点的逆路径 
void AllPath1(BTNode *b,ElemType path[],int pathlen){	//path[]存储路径【相当于一个栈】,pathlen记录路径长度 
	int i;							//调用AllPath1函数时,传进来的path[]是空数组,pathlen为0; 
	if(b!=NULL){
		if(b->lchild==NULL && b->rchild==NULL){		//若b为叶子结点
			printf("%c到根结点的逆路径:%c->",b->data,b->data);	//打印叶子结点
			for(i=pathlen-1;i>0;i--)		//打印路径时,并没有修改栈顶指针pathlen的值 
				printf("%c->",path[i]);			//所以每次递归遍历的路径存储在上次递归路径的后面 
			printf("%cn",path[0]);
		}else{
			path[pathlen] = b->data;	//将当前结点放入路径中 
			pathlen++;					//路径长度加1
			AllPath1(b->lchild,path,pathlen);	//递归扫描左子树
			AllPath1(b->rchild,path,pathlen);	//递归扫描右子树  
		} 
	}
} 


//采用先序遍历方法输出第一条最长的逆路径
void LongPath1(BTNode *b,ElemType path[],int pathlen,ElemType longpath[],int &longpathlen ){
	int i;												//longpath[]保存当前最长路径,每次递归的路径长度都可能被修改
	if(b==NULL){	//若当前节点为空 
		if(pathlen>longpathlen){	//若当前路径更长,将路径保存 
			for(i=pathlen-1;i>=0;i--)
				longpath[i]=path[i];
			longpathlen= pathlen;
		}
	} else{
		path[pathlen] = b->data;
		pathlen++;
		LongPath1(b->lchild,path,pathlen,longpath,longpathlen);
		LongPath1(b->rchild,path,pathlen,longpath,longpathlen);
	}
} 

//采用后序非递归遍历方法输出所有从叶子结点到根结点的逆路径
void AllPath2(BTNode *b){
	BTNode * st[MaxSize];	//定义一个顺序栈st
	int top=-1;			//栈顶指针初始化
	BTNode *p,*r;
	bool flag;
	p=b;
	do{	//至少循环一次 
		while(p!=NULL){		//扫描结点p的所有左下结点并进栈
			top++;
			st[top] = p;	//结点p进栈
			p=p->lchild;	//移动到左孩子 
			
		}
		r=NULL;		//r指向刚刚访问的结点,初始时为空
		flag=true;	//flag为真表示正在处理栈顶结点
		while(top>-1 && flag){	//栈不空且flag为真时进入循环 
			p=st[top];		//取出当前的栈顶结点p
			if(p->rchild == r){		//若结点p的右孩子为空或者为刚刚访问过的结点
				if(p->lchild==NULL && p->rchild==NULL){		//若为叶子结点,输出栈中所有结点值
					printf("%c到根结点逆路径:",p->data);
					for(int i=top;i>0;i--){
						printf("%c->",st[i]->data);
					} 
					printf("%cn",st[0]->data);
					 
				} 
				top--;		//退栈
				r=p;		//r指向刚访问过的结点 
			}else{
				p=p->rchild;	//转向处理其右子树
				flag=false;		//表示当前不是处理栈顶结点 
			}	 
		} 
	} while(top>-1);	//栈空时,退出循环 
} 

//采用层次遍历输出所有从叶子结点到根结点的逆路径 
void AllPath3(BTNode *b){
	//定义顺序队列
	struct snode{
		BTNode *node;		//存放当前结点指针
		int parent;			//存放双亲结点在队列中的位置 
	}Qu[MaxSize]; 
	int front,rear,p;		//定义队头和队尾指针
	front=rear=-1;			//置队列为空队列
	rear++;
	Qu[rear].node=b;		//根结点指针进入队列
	Qu[rear].parent=-1;		//根结点没有双亲结点
	while(frontlchild==NULL && b->rchild==NULL){	//若b为叶子结点
			printf("%c到根结点逆路径:",b->data);
			p=front;
			while(Qu[p].parent != -1){
				printf("%c->",Qu[p].node->data);
				p=Qu[p].parent;
			} 
			printf("%cn",Qu[p].node->data);
		} 
		if(b->lchild!=NULL){	//若有左孩子,将其进队
			rear++;
			Qu[rear].node=b->lchild;
			Qu[rear].parent=front; 
			
		}
		if(b->rchild!=NULL){	//若有右孩子,将其进队
			rear++;
			Qu[rear].node=b->rchild;
			Qu[rear].parent=front; 
		}
	} 
	
}

int main(){
	BTNode *b;
	ElemType path[MaxSize],longpath[MaxSize];
	int i,longpathlen=0;
	CreatBTree(b,"A(B(D,E(H(J,K(L,M(,N))))),C(F,G(,I)))");
	printf("二叉树b:");
	DispBTree(b);printf("n");
	printf("先序遍历方法:n");
	AllPath1(b,path,0);
	LongPath1(b,path,0,longpath,longpathlen);
	printf("第一最长逆路径长度:%dn",longpathlen);
	printf("第一最长逆路径:");
	for(i=longpathlen-1;i>=0;i--)
		printf("%c",longpath[i]);
	printf("n");
	printf("后序非递归遍历方法:n");
	AllPath2(b);
	printf("层次遍历方法:n");
	AllPath3(b);
	DestroyBTree(b);
	return 1;
}


 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/892408.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号