多叉树的DFS深度优先遍历,回溯法的基础算法之一

一、前言

多叉树一般用于解决回溯问题。
想必大家都学过二叉树,以及二叉树的深度优先遍历和广度优先遍历,我们思考:能不能将二叉树的DFS转化为多叉树的DFS?

二、多叉树的结构

多叉树的本质,就是一棵普通的树,比如下图:
如果忽略将来的变化,那么,这棵树可以认为是一个未满的4叉树。不满的4叉树


由于多叉树代码实现比较复杂,在此不介绍。

三、从二叉树看多叉树

二叉树是非常特殊的,每一个节点,它只有2个子节点。并且,这两个节点可以直接拿到,即:
left指向左子节点,right指向右子节点。通过left、right就可以拿到它的左右节点。
多叉树是更加普遍的树结构,它满足树的层序性,满足最多一个父节点的性质。

四、二叉树的DFS,为什么不适用于多叉树?【以中序遍历为例】

我们知道,二叉树遍历满足口诀:“节点,左子树,右子树”。
链接
二叉树中序遍历
如果为二叉树的节点,增加一条子树X,位于右子树的右边。
结构为【左子树,右子树,X子树】
此时,使用中序遍历的口诀,我们发现,子树X遍历不到。【每一层子树X都遍历不到】。

五、解决多叉树遍历问题

多叉树遍历问题的关键在于,由于语句的次序性,每一次只能访问一个节点。
解释:二叉树的递归函数A中,访问节点值的操作,只发生一次,然后将访问左右子节点值的操作,交给子递归函数A’。
即使多出一个子树X,也不会改变语句的次序性。
解决方案:二叉树访问节点Node后,将左右子节点的访问交给子递归函数,那么,也可以把X子树的访问,同样交给子递归函数。
伪代码

void function(Node root){
	// 如果节点为null,返回
	if(node == null) return;
	
	// 访问节点
	print(root.val);
	
	//依次访问左子、右子和X子树
	function(root.left);
	function(root.right);
	function(root.X);
}

做完这一步,相信你对解决其它的多叉树遍历问题也有所了解。
然而,新问题出现了:
function函数,有指向性,直接拿到多叉树的第i个子树,然后遍历。
对于普遍的二叉树,这是没法做到的。

六、解决普遍多叉树,无指向性问题的两种方案

第一,定义节点顺序

既然无指向性,最简单的方案就是提供指向性。
比如对于4叉树,定义为:
第一个子节点fir,
第二个sec,
第三个thi,
第四个four。
这样,访问时就可以依次访问了。
当然,这种解决方案,不适用于外部复杂情况


第二,不考虑顺序,直接遍历子节点集合

如果多叉树提供一种方法,能够返回子节点集合。
那么,我们可以使用List存储子节点集合。
然后用foreach方法,遍历所有子树。
这种方案,使用时不考虑节点间的顺序性。

七、结语

我是蚊子码农,如有补充或者疑问,欢迎在评论区留言。个人的知识体系可能没有那么完善,希望各位多多指正,谢谢大家。

  • 19
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值