【数据结构】【树的遍历算法】【python】树的各种遍历算法

二叉树或是树的遍历在各种面试和考试中都十分常见,本文主要是关于树的各种遍历算法.点赞过50更新算法动画,如果还有需要的遍算法可以留言哦

(1)二叉树的前中后遍历

以中序遍历为例,中序遍历的遍历顺序为:左、根、右,即以当前节点为例,先遍历左子节点,再是当前节点,再是右子节点。对于下图来说,**中序遍历的结果为:4,2,5,1,3.**伪代码如下:

def midorder(root):#中序遍历
	if root.left:#有左子节点
		midorder(root.left)
	op(root)#对当前节点操作
	if root.right:#有右子节点
		midorder(root.right)
	

在这里插入图片描述
当代码执行到1节点,也就是根节点时,先遍历以1节点的左子节点,即2节点。以递归的方式来说,那就会递归到2节点,即先执行midorder(root.left),第二个递归函数进入调用栈,对以2节点为根节点的子树,先递归到4节点,即先执行midorder(root.left),第三个递归函数进入调用栈,而4节点没有子节点,因此对当前节点也就是4节点进行op,打印4节点的信息,第三个递归函数执行完成,退栈。返回第二个递归函数,执行过midorder(root.left)后,继续执行op,打印2节点的信息,然后再判断是否有右子节点,并再次递归调用,将函数压入栈。故中序遍历代码:

def inorderTraversal(self, root):
        result = []
        def fun(node):
            if node.left:
                fun(node.left)
            result.append(node.val)
            if node.right:
                fun(node.right)
            
        if root:
            fun(root)
        return result

而先序遍历,后序遍历的写法就是把对当前节点的访问顺序放到最前面和最后面。
对于三种遍历,也可以用迭代的方式写代码。因为递归的本质就是函数调用入栈的过程,如果我们自己建立栈来模拟系统栈,就可以不使用递归来实现。

(2)二叉树的深度(深度优先遍历):

其实前中后序三种遍历也是深度优先遍历。如果要求树的深度,也可以用深度优先遍历的思路。因此下面的深度优先遍历代码可以说是更普遍的、通用的DFS遍历。所谓DFS,就是一条路走到黑,不碰南墙不回头。例如一直遍历左子节点,直到没有左子节点为止。
在这里插入图片描述
对上面的例题,代码如下:left和right的值是向左和向右遍历得到的深度值。如果遇到节点不存在的情况,返回值为0,代表深度为0,否则就返回的是左子树和右子树中深度的最大值。

class Solution(object):
    def calculateDepth(self, root):
        if not root:
            return 0
        left = self.calculateDepth(root.left)
        right = self.calculateDepth(root.right)
        return max(left,right) + 1

或者写成这样:

class Solution(object):
    def maxDepth(self, root):
        def dfs(node):
            if not node:
                return 0

            L = dfs(node.left)
            R = dfs(node.right)
            return max(L,R)+1
        
        return dfs(root)

(3)二叉树的层序遍历

层序遍历是利用队列,对于python可以使用deque数据结构,也可以不使用。但本质上都是模拟队列的操作。先将根节点入队,再对队列进行循环操作:如果队列未空,则将队头元素弹出,对队头元素操作,并将其子节点放入对内。层序遍历代码如下:

#注意!下面代码是二叉树!
def solution(root):
    if not root:
        return []  # 如果树为空,返回空数组

    res = []  # 初始化结果数组
    queue = deque([root])  # 初始化队列,首先包含根节点
    while queue:
        current = queue.popleft()  # 从队列中取出第一个节点
        res.append(current.value)  # 将当前节点的值追加到结果数组

        # 将当前节点的左子节点添加到队列中
        if node.left:
            queue.append(node.left)
        
        # 如果当前节点有右子节点,将其加入队列
        if node.right:
            queue.append(node.right)

    return res  # 返回结果数组

在这里插入图片描述
对于上图进行层序遍历,先将1节点入队,入队列后进入循环迭代操作:当队列未空就一直循环。1节点出队,为current,并将其增添进res,1节点有左右节点,则2、3节点进入队列等待下一次循环。对2节点进行操作,2节点出队,添加进入res,并将其子节点即4、5节点入队列,等待之后的操作。2节点处理结束后,当前队列剩余节点为3、4、5节点3节点出队但没有子节点,故只用添加进res即可。4、5处理方式同3,循环结束,得到res为1、2、3、4、5.

#注意!下面代码不是二叉树,而是树!
def solution(root):
    if not root:
        return []  # 如果树为空,返回空数组

    res = []  # 初始化结果数组
    queue = deque([root]) # 初始化队列,首先包含根节点
    while queue:
        current = queue.popleft()  # 从队列中取出第一个节点
        res.append(current.value)  # 将当前节点的值追加到结果数组

        # 将当前节点的所有子节点添加到队列中
        for child in current.childNodes:
            queue.append(child)

    return res  # 返回结果数组

上述代码是对于树进行的层序遍历,因此一个节点的子节点个数可以大于2。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值