LeetCode,二叉树的层次遍历、逆转

1. 基本知识

1.1 二叉树的层次遍历

二叉树的层次遍历是指一层一层地遍历二叉树,并按照每层为一个列表返回,实例如下,

图1. 二叉树的层次遍历

二叉树1的层次遍历结果为:[[1] [2, 3] [4, 5, 6, 7]];

二叉树2的层次遍历结果为:[[1], [2, 3], [6, 7]]

层次遍历的特点为不按照左右节点优先遍历某 一遍,而是先将同一层的元素先全部遍历结束。因此,层次遍历的算法考虑先将某一层的节点存储如列表,等访问完该层后,再访问该层所有的左右节点。算法步骤如下,

初始化:首先定义访问列表to_visit为下一层需要访问的所有节点,初始化为只含有根节点的列表;定义结果列表r:

(1)遍历变量to_visit,

(2)当前节点的值存入结果;

(3)访问列表to_visit的值更新append为当前列表中所有左右节点;

直到to_visit为空列表[]时,返回结果。

1.2 逆二叉树

逆二叉树为将二叉树的左右枝反转。以图1为例,将其进行逆转之后结果如下,

图2. 二叉树逆转

在进行二叉树的遍历时,每个节点的左右都要交换,直到节点为空,因此,从该思路来看,该逆转的思路是递归算法。算法如下,

(1)初始化,从根部节点开始;

(2)若是当前节点有右半部分,那么其新的左半部分=右半部分;否则左半部分为空;右节点为根节点递归逆转;

(3)若是当前节点有左半部分,那么其新的右半部分=左半部分;否则右半部分为空;左节点为根节点递归逆转。

直到节点为空为止。

在这个里面有一个细节值得注意,在右半部分非空的时候,不能直接将节点的左半部分赋值为右半部分,需要暂时存储起来,等到判断完左半部分之后才能处理右半部分的赋值。

一定注意!!!:在Python中,object1=object,在修改object1的时候,object也会随之改变,因其地址为相同的,指向同一地址。在Python内置的数据类型,tmp=a.clone(),可以避免在tmp发生改变时改变a的值。但是自己定义的类就不能这样操作啦~~~~参考,让一个对象=另一个对象,修改一个对象的值,如何不影响另一个的值_VR_wangkr的博客-CSDN博客_java对象赋值给另一个对象怎么才能不变成一个对象​​​​​​

2. 代码

2.1 二叉树的层次遍历

LeetCode107,力扣

给你二叉树的根节点 root ,返回其节点值 自底向上的层序遍历 。 (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历)

图3. 层数遍历示例

代码如下,

# Definition for a binary tree node.
class TreeNode(object):
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right

    def set_left(self, left):
        self.left = left

    def set_right(self, right):
        self.right = right

class Solution(object):
    def levelOrderBottom(self, root):
        """
        :type root: TreeNode
        :rtype: List[List[int]]
        """
        r = []
        if root == None:
            return []
        current = [root]
        while current != []:
            tmp = []
            r_tmp = []
            for node in current:
                r_tmp.append(node.val)
                if node.left != None:
                    tmp.append(node.left)
                if node.right != None:
                    tmp.append(node.right)
            r.append(r_tmp)
            current = tmp

        r.reverse()
        return r

if __name__ == '__main__':
    root = [1,  2, 3]
    node1 = TreeNode(3)
    node2 = TreeNode(9)
    node3 = TreeNode(20)
    node4 = TreeNode(15)
    node5 = TreeNode(7)

    node1.set_left(node2)
    node1.set_right(node3)

    node3.set_left(node4)
    node3.set_right(node5)

    sol = Solution()
    # r = sol.preorderTraversal(node1)
    r = sol.levelOrderBottom(node1)
    r1 = sol.invertTree(node1)
    print(r)

 2.2 逆二叉树

LeetCode226,力扣

给你一棵二叉树的根节点 root ,翻转这棵二叉树,并返回其根节点。

图4. 逆二叉树示例

代码如下,

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
    def invertTree(self, root):
        """
        :type root: TreeNode
        :rtype: TreeNode
        """
        if root == None:
            return 
        r = root
        flag = 0 
        if root.right != None:
            flag = 1
            tmp = self.invertTree(root.right)
            
        if root.left != None:
            root.right =  self.invertTree(root.left)
        else:
            root.right = None

        if flag == 1:
            root.left = tmp
        else:
            root.left = None
        return r

<think>好的,我现在需要帮助用户理解广度优先遍历层次遍历的区别以及它们在和图结构中的应用。首先,我得回顾一下这两个概念的定义和特点。 根据引用[2],广度遍历通常指的是分层遍历,也就是层次遍历。例如在二叉树中,层次遍历会逐层访问节点,先访问根节点,然后是子节点,依此类推。而广度优先遍历(BFS)在图结构中类似于层次遍历,从一个顶点出发,先访问相邻顶点,再访问相邻顶点的相邻顶点,如引用[3]和[5]所述。这说明在结构中,层次遍历和广度优先遍历其实是同一个概念的不同表述,都是按层次进行的。 不过用户可能想知道它们的区别。这里可能需要指出,层次遍历通常特指结构中的分层访问,而广度优先遍历(BFS)是更通用的术语,适用于图和。例如,在图结构中,由于存在环路和多个连接方式,BFS需要记录已访问节点以避免重复,而层次遍历则无需担心环路,因为是无环的。 接下来,实现方法方面,层次遍历和图的BFS都使用队列结构。例如,引用[3]提到图的BFS需要队列来保存待访问的节点,而引用[2]中的二叉树层次遍历同样使用队列。不过图的BFS还需要维护一个访问标记数组,以防止重复访问,这在中是不需要的,因为结构没有环路。 在应用方面,层次遍历用于二叉树的分层处理,如计算层数或节点数;而图的BFS常用于最短路径问题,如引用[3]提到的图中点的层次问题。例如,在社交网络中寻找最短连接路径,或者在迷宫问题中找到最短出口路径。 需要确保回答中正确引用资料。例如,引用[2]说明层次遍历是广度遍历中的表现,引用[3]和[5]解释图的BFS实现方式。同时,区分和图的不同应用场景,如层次遍历用于的分层处理,BFS用于图的最短路径。 最后,生成相关问题时要围绕用户的问题扩展,例如实现方法、区别对比、应用场景等。确保问题有针对性,帮助用户深入理解。</think>### 广度优先遍历层次遍历的区别及应用 #### 1. **核心概念** - **层次遍历**:特指(如二叉树、多叉)中按层级逐层访问节点的遍历方式,例如从根节点开始依次访问每一层的所有子节点[^2]。 - **广度优先遍历(BFS)**:是一种通用的遍历算法,适用于和图结构。其核心是“先访问当前层的所有节点,再访问下一层节点”[^3]。 #### 2. **主要区别** | **特征** | **层次遍历** | **广度优先遍历(BFS)** | |---------------------|----------------------------|------------------------------| | 适用结构 | 仅限(如二叉树) | 、图(包括有向图和无向图) | | 是否需要标记已访问 | 不需要(无环路) | 需要(图可能存在环路)[^5] | | 典型应用场景 | 计算的高度、分层统计节点 | 图的最短路径、拓扑排序 | #### 3. **实现方法** - **层次遍历(以二叉树为例)** 使用队列逐层记录节点,代码示例如下(Python): ```python def level_order(root): queue = [root] while queue: node = queue.pop(0) print(node.val) if node.left: queue.append(node.left) if node.right: queue.append(node.right) ``` 该过程确保按层输出节点值,如引用[2]所述的分层遍历逻辑。 - **图的广度优先遍历** 需要队列和访问标记数组,代码框架如下(以邻接表存储的图为例): ```python def bfs(graph, start): visited = [False] * len(graph) queue = [start] visited[start] = True while queue: u = queue.pop(0) for v in graph[u]: if not visited[v]: visited[v] = True queue.append(v) ``` 此方法避免重复访问,适用于图中点的层次分析[^5]。 #### 4. **应用场景** - **层次遍历**: 例如二叉树的层序遍历、计算的宽度或高度[^2]。 - **广度优先遍历**: - 图的连通性检测:判断两个节点是否连通。 - 最短路径问题:在无权图中找到两点间最短路径。 - 社交网络分析:通过BFS寻找“六度空间”内的关联用户。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值