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

二叉树的所有路径

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

二叉树的所有路径

提示:兰有秀兮菊有芳,怀佳人兮不能忘

文章目录
  • 题目
  • 递归(回溯)
  • 递归(不回溯)
  • 迭代
  • 运行截图
  • 总结


题目

给你一个二叉树的根节点 root ,按任意顺序 ,返回所有从根节点到叶子节点的路径


输入:root = [1,2,3,null,5]
输出:[“1->2->5”,“1->3”]

思路:简单来说就是定义一个result 用来存放结果 一个path 用来存放路径 但是很多人被搞蒙的是需不需要回溯,若是在本次中的path改变了 就需回溯,因为下一个路径的路不能是上一个走过的路,若是没有改变path的值他们走的路自己不同

递归(回溯)
#include
#define ElemType int
using namespace std;
typedef struct BiNTree{
	struct BiNTree* Lchild;
	ElemType data;
	struct BiNTree* Rchild;
}BiNTree;
 
vector result;
void Creat(BiNTree* &T){
	int val;
	BiNTree* cur;//定义一个cur 
	queue Q;
	queue TreeQue;
	cout<<"请输入层序遍历的序列"<
		cout<<"树为空"< 
		T=(BiNTree*)malloc(sizeof(BiNTree));
		T->data=Q.front(); 
		TreeQue.push(T);
	}
	Q.pop();
	while(!Q.empty()){//我们每一次处理 处理的都是左右孩子,所以也就需要两个if
		cur=TreeQue.front();//取出此时树队中的第一元素
		if(Q.front()==-1){//此时这个结点值为NULL  
			cout<data<<"左孩子为空"<Lchild=NULL; 
		}
		else{//新生成一个树结点用来存放此时的结点信息 
			cout<data<<"左孩子为"<Lchild=(BiNTree*)malloc(sizeof(BiNTree)) ;
			cur->Lchild->data=Q.front();
			TreeQue.push(cur->Lchild);
		}
		Q.pop();//处理完数据之后需要弹出 来取此结点右子树的值 
		//上面的if  else 是处理结点左孩子  下面我们来处理右孩子 
		if(Q.front()==-1){
			cout<data<<"右孩子为空"<Rchild=NULL;
		} 
		else{
			cout<data<<"右孩子为"<Rchild=(BiNTree*)malloc(sizeof(BiNTree));
			cur->Rchild->data=Q.front();
			TreeQue.push(cur->Rchild); 
		}
		Q.pop();
		TreeQue.pop();
	}
} 
void PreOrder(BiNTree* T,vector &result,string &path){
	if(T->Lchild==NULL&&T->Rchild==NULL){//遇到叶子结点一路返回 
		path+=to_string(T->data);
		result.push_back(path);
		return;
	}
	//此时不是叶子节点  我们就需要深入 找到叶子结点
	if(T->Lchild){ 
		string temp=path;
		path=path+to_string(T->data)+"->";
		PreOrder(T->Lchild,result,path);
		path=temp;//回溯
	} 
	if(T->Rchild){
		string temp=path;
		path=path+to_string(T->data)+"->";
		PreOrder(T->Rchild,result,path);
		path=temp;//回溯
	}
} 
string Deal(BiNTree* T){
	if(T==NULL) return " ";
	string path;
	vector result;
	PreOrder(T,result,path);
	cout<<"此时的路径是"<
		cout<
	BiNTree* T=NULL;
	Creat(T); 
	Deal(T);	
}
递归(不回溯)
#include
#define ElemType int
using namespace std;
typedef struct BiNTree{
	struct BiNTree* Lchild;
	ElemType data;
	struct BiNTree* Rchild;
}BiNTree;
 
vector result;
void Creat(BiNTree* &T){
	int val;
	BiNTree* cur;//定义一个cur 
	queue Q;
	queue TreeQue;
	cout<<"请输入层序遍历的序列"<
		cout<<"树为空"< 
		T=(BiNTree*)malloc(sizeof(BiNTree));
		T->data=Q.front(); 
		TreeQue.push(T);
	}
	Q.pop();
	while(!Q.empty()){//我们每一次处理 处理的都是左右孩子,所以也就需要两个if
		cur=TreeQue.front();//取出此时树队中的第一元素
		if(Q.front()==-1){//此时这个结点值为NULL  
			cout<data<<"左孩子为空"<Lchild=NULL; 
		}
		else{//新生成一个树结点用来存放此时的结点信息 
			cout<data<<"左孩子为"<Lchild=(BiNTree*)malloc(sizeof(BiNTree)) ;
			cur->Lchild->data=Q.front();
			TreeQue.push(cur->Lchild);
		}
		Q.pop();//处理完数据之后需要弹出 来取此结点右子树的值 
		//上面的if  else 是处理结点左孩子  下面我们来处理右孩子 
		if(Q.front()==-1){
			cout<data<<"右孩子为空"<Rchild=NULL;
		} 
		else{
			cout<data<<"右孩子为"<Rchild=(BiNTree*)malloc(sizeof(BiNTree));
			cur->Rchild->data=Q.front();
			TreeQue.push(cur->Rchild); 
		}
		Q.pop();
		TreeQue.pop();
	}
} 
void PreOrder(BiNTree* T,vector &result,string path){
	if(T->Lchild==NULL&&T->Rchild==NULL){//遇到叶子结点一路返回 
		path+=to_string(T->data);
		result.push_back(path);
		return;
	}
	//此时不是叶子节点  我们就需要深入 找到叶子结点
	if(T->Lchild){ 
		PreOrder(T->Lchild,result,path+to_string(T->data)+"->");
	} 
	if(T->Rchild){
		PreOrder(T->Rchild,result,path+to_string(T->data)+"->");
	}
} 
string Deal(BiNTree* T){
	if(T==NULL) return " ";
	string path;
	vector result;
	PreOrder(T,result,path);
	cout<<"此时的路径是"<
		cout<
	BiNTree* T=NULL;
	Creat(T); 
	Deal(T);	
}

迭代

记住一句关键 就是每一个结对对应一个字符串所以你要使用的结构是栈其中的元素是string 主要就是同步 对结点进行什么操作 相应的对结点对印的路径进行什么操作,记住此结点路径是在上一个结点路径的结果上进行加长的
你就可以写出代码 解析放在代码中了

#include
#define ElemType int
using namespace std;
typedef struct BiNTree{
	struct BiNTree* Lchild;
	ElemType data;
	struct BiNTree* Rchild;
}BiNTree;
 
void Creat(BiNTree* &T){
	int val;
	BiNTree* cur;//定义一个cur 
	queue Q;
	queue TreeQue;
	cout<<"请输入层序遍历的序列"<
		cout<<"树为空"< 
		T=(BiNTree*)malloc(sizeof(BiNTree));
		T->data=Q.front(); 
		TreeQue.push(T);
	}
	Q.pop();
	while(!Q.empty()){//我们每一次处理 处理的都是左右孩子,所以也就需要两个if
		cur=TreeQue.front();//取出此时树队中的第一元素
		if(Q.front()==-1){//此时这个结点值为NULL  
			cout<data<<"左孩子为空"<Lchild=NULL; 
		}
		else{//新生成一个树结点用来存放此时的结点信息 
			cout<data<<"左孩子为"<Lchild=(BiNTree*)malloc(sizeof(BiNTree)) ;
			cur->Lchild->data=Q.front();
			TreeQue.push(cur->Lchild);
		}
		Q.pop();//处理完数据之后需要弹出 来取此结点右子树的值 
		//上面的if  else 是处理结点左孩子  下面我们来处理右孩子 
		if(Q.front()==-1){
			cout<data<<"右孩子为空"<Rchild=NULL;
		} 
		else{
			cout<data<<"右孩子为"<Rchild=(BiNTree*)malloc(sizeof(BiNTree));
			cur->Rchild->data=Q.front();
			TreeQue.push(cur->Rchild); 
		}
		Q.pop();
		TreeQue.pop();
	}
} 

//关键的一句话 每一个结点都有一个对应的字符串 
void PreOrder(BiNTree* T,vector &result){
	stack S;
	stack path;
	if(T==NULL) return;
	S.push(T);
	path.push(to_string(T->data));//因为本来是整形 这里要转换成字符串型  使用to_string()便可  
	while(!S.empty()){
		cout<<"进入while"; 
		BiNTree* cur=S.top();//取出当前栈顶元素
		cout<<"此时栈顶元素是"<data<Lchild==NULL&&cur->Rchild==NULL){
			//说明此时的路径 可以放在结果集中
			cout<<"找到此时的叶子结点"<data<//如果不是叶子结点  则将此结点的的左右孩子放入栈集中 
			if(cur->Rchild){
				S.push(cur->Rchild);
				path.push(str1+"->"+to_string(cur->Rchild->data));
				cout<<"将右结点"<Rchild->data<<"放入栈中"<Lchild){
				S.push(cur->Lchild);//记住右左顺序
				path.push(str1+"->"+to_string(cur->Lchild->data));
				cout<<"将左结点"<Lchild->data<<"放入栈中"<
	vector result;//用来存放结果集  这里存放的元素也是string  
	PreOrder(T,result);
	//此时遍历二维向量
	cout<<"最后发现的路径是"<
		cout<
	BiNTree* T=NULL;
	Creat(T); 
	Deal(T);	
}
运行截图

总结

若是感觉文章对你有用的话 不要mean一个赞 你的点赞是作者奋斗的的动力

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

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

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