动画演示|二叉树de深度优先搜索DFS
原理
深度优先搜索(DFS)遵循这样一条准则:总是沿着节点的一条边,一路走到黑,而后返回到出发节点,再继续下一条边,假如找到目标节点,则返回,假如找不到,就会遍历完一律节点。因为二叉树只有两条边,所以DFS对二叉树来说,就是先把左子树遍历完,再遍历右子树,等同于先序遍历
。
下面用动画演示了查找5的过程:
DFS动画演示
原理很简单清晰,不过俗话说得好:
细节是魔鬼
下面来看看如何用Swfit实现DFS,给出少量编程中需要注意的问题。
DFS的递归实现
因为递归很符合算法逻辑,首先来看看递归的实现,先定义二叉树的节点:
public class TreeNode { public var val: Int //节点的值 public var left: TreeNode? //左节点 public var right: TreeNode? //右节点 public init(_ val: Int) { self.val = val self.left = nil self.right = nil }}
完整的递归实现:
func dfsTree(_ root: TreeNode?, _ dst: Int) -> TreeNode? { if (root == nil) { return nil } if (root?.val == dst) { return root } var dstNode = self.dfsTree(root?.left, dst) if (dstNode == nil) { dstNode = self.dfsTree(root?.right, dst) } return dstNode}
因为二叉树本身就是递归定义的,所以用递归调用显得很自然,只需先解决left,再解决right就可。
DFS的非递归实现
因为大部分递归的效率较低,尝试把递归开展为循环,这时有两个问题需要考虑:
- 因为当左分支访问完成后,要回到节点获取右分支,需要记录访问过的节点,这里用Array作为栈来存储。
- 节点有三种状态:
未访问
、已访问
、分支都已访问完成
。
如动画中演示的,蓝色
对应未访问
,即树的初始状态;黄色
代表节点已访问
,已放入栈中;灰色对应左右分支都已访问
,又该如何存储呢?为保存左右分支的访问状态,这里连同节点一起用元组保存在栈中:
(node:TreeNode, isCheckLeft:Bool, isCheckRight:Bool)
完整的非递归实现如下:
func loopDfsTree(_ root: TreeNode?, _ dst: Int) -> TreeNode? { if (root == nil) { return nil } var checkNodes = Array<(node:TreeNode, isCheckLeft:Bool, isCheckRight:Bool)>() checkNodes.append((root!, false, false)) while checkNodes.last != nil { var nodeInfo = (checkNodes.popLast())! let dstNode = nodeInfo.node if (dstNode.val == dst) { return dstNode } if (dstNode.left != nil && nodeInfo.isCheckLeft == false) { nodeInfo.isCheckLeft = true checkNodes.append(nodeInfo) checkNodes.append(((dstNode.left)!, false, false)) } else if (dstNode.right != nil && nodeInfo.isCheckRight == false) { nodeInfo.isCheckRight = true checkNodes.append(nodeInfo) checkNodes.append(((dstNode.right)!, false, false)) } else { } } return nil}
思考题
比照DFS的递归实现和非递归实现,为什么递归实现不需要保存节点的状态信息?欢迎你的留言,相信经过深度思考的知识,才会历久弥新。
说明
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » 动画演示|二叉树de深度优先搜索DFS
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » 动画演示|二叉树de深度优先搜索DFS