首页 > 编程语言 >代码随想录算法训练营第十四天|144. 二叉树的前序遍历、145. 二叉树的后序遍历、94. 二叉树的中序遍历

代码随想录算法训练营第十四天|144. 二叉树的前序遍历、145. 二叉树的后序遍历、94. 二叉树的中序遍历

时间:2023-05-23 14:45:45浏览次数:43  
标签:遍历 TreeNode val self 第十四天 right 二叉树 root left

【参考链接】

1.满二叉树,完全二叉树,二叉搜索树(有数值,有序树)。

2.平衡二叉搜索树:又被称为AVL(Adelson-Velsky and Landis)树,且具有以下性质:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。

3.优先级队列其实是一个堆,堆就是一棵完全二叉树,同时保证父子节点的顺序关系。

4.二叉树可以链式存储(指针),也可以顺序存储(数组)。

5.二叉树主要有两种遍历方式:

  1. 深度优先遍历:先往深走,遇到叶子节点再往回走。
  2. 广度优先遍历:一层一层的去遍历。

6.栈其实就是递归的一种实现结构。

1 #二叉树的定义
2 class TreeNode:
3     def __init__(self,value):
4         self.value = value
5         self.left = None
6         self.right = None

java版本

 1 //二叉树的定义
 2 public class TreeNode{
 3     int val;
 4     TreeNode left;
 5     TreeNode right;
 6     TreeNode() {}
 7     TreeNode(int val) {
 8         this.val = val;
 9 }
10     TreeNode(int val, TreeNode left, TreeNode right){
11         tihs.val = val
12         this.left = left
13         this.right = right
14 }

7.递归三要素:

  1. 确定递归函数的参数和返回值: 确定哪些参数是递归的过程中需要处理的,那么就在递归函数里加上这个参数, 并且还要明确每次递归的返回值是什么进而确定递归函数的返回类型。

  2. 确定终止条件: 写完了递归算法, 运行的时候,经常会遇到栈溢出的错误,就是没写终止条件或者终止条件写的不对,操作系统也是用一个栈的结构来保存每一层递归的信息,如果递归没有终止,操作系统的内存栈必然就会溢出。

  3. 确定单层递归的逻辑: 确定每一层递归需要处理的信息。在这里也就会重复调用自己来实现递归的过程。

144. 二叉树的前序遍历

【代码】

 1 # Definition for a binary tree node.
 2 # class TreeNode(object):
 3 #     def __init__(self, val=0, left=None, right=None):
 4 #         self.val = val
 5 #         self.left = left
 6 #         self.right = right
 7 class Solution(object):
 8     def preorderTraversal(self, root):
 9         """
10         :type root: TreeNode
11         :rtype: List[int]
12         """
13         if not root:
14             return []
15         
16         left = self.preorderTraversal(root.left)
17         right = self.preorderTraversal(root.right)
18 
19         return [root.val] + left + right

145. 二叉树的后序遍历

【代码】

 1 # Definition for a binary tree node.
 2 # class TreeNode(object):
 3 #     def __init__(self, val=0, left=None, right=None):
 4 #         self.val = val
 5 #         self.left = left
 6 #         self.right = right
 7 class Solution(object):
 8     def postorderTraversal(self, root):
 9         """
10         :type root: TreeNode
11         :rtype: List[int]
12         """
13         if not root :
14             return []
15 
16         left = self.postorderTraversal(root.left)
17         right = self.postorderTraversal(root.right)
18 
19         return left + right + [root.val]

94. 二叉树的中序遍历

【代码】

 1 # Definition for a binary tree node.
 2 # class TreeNode(object):
 3 #     def __init__(self, val=0, left=None, right=None):
 4 #         self.val = val
 5 #         self.left = left
 6 #         self.right = right
 7 class Solution(object):
 8     def inorderTraversal(self, root):
 9         """
10         :type root: TreeNode
11         :rtype: List[int]
12         """
13         if not root :
14             return []
15 
16         left = self.inorderTraversal(root.left)
17         right = self.inorderTraversal(root.right)
18 
19         return left + [root.val] + right

8.递归的实现就是:每一次递归调用都会把函数的局部变量、参数值和返回地址等压入调用栈中,然后递归返回的时候,从栈顶弹出上一次递归的各项参数,所以这就是递归为什么可以返回上一层位置的原因。

9.前序遍历是中左右,每次先处理的是中间节点,那么先将根节点放入栈中,然后将右孩子加入栈,再加入左孩子。

【代码】

 1 class TreeNode(object):
 2     def __init__(self, val=0, left=None, right=None):
 3         self.val = val
 4         self.left = left
 5         self.right = right
 6 
 7 
 8 def preorderTraversal(root: TreeNode):
 9         # 根结点为空则返回空列表
10     if not root:
11         return []
12     stack = [root]
13     result = []
14     while stack:
15         node = stack.pop()
16         # 中结点先处理
17         result.append(node.val)
18         # 右孩子先入栈
19         if node.right:
20             stack.append(node.right)
21         # 左孩子后入栈
22         if node.left:
23             stack.append(node.left)
24     print(result)
25 
26 if __name__ == '__main__':
27     root = TreeNode(1)
28     node1 = TreeNode(2)
29     node3 = TreeNode(3)
30     root.left = None
31     root.right = node1
32     node1.left = node3
33     preorderTraversal(root)

10.迭代法:前序遍历

【代码】

class Solution(object):
    def preorderTraversal(self, root):
        """
        :type root: TreeNode
        :rtype: List[int]
        """
        #1.递归法
        # if not root:
        #     return []
        
        # left = self.preorderTraversal(root.left)
        # right = self.preorderTraversal(root.right)

        # return [root.val] + left + right

        #2.迭代法
        if not root:
            # 根结点为空则返回空列表
            return []

        stack = [root] #栈 先将根节点入栈
        result = [] #存放遍历结果

        while stack: #栈不为空时
            node = stack.pop() #将根节点弹出栈
            #并将根节点的值存放在result中
            result.append(node.val)
            #右孩子先入栈
            if node.right:#当有右孩子的时候
                stack.append(node.right)
            #左孩子后入栈
            if node.left:
                stack.append(node.left)
        
        return result

11.迭代法:后序遍历:先序遍历是中左右——》调整代码左右顺序——》中右左——》反转result数组——》左右中

【代码】

 1 class Solution(object):
 2     def postorderTraversal(self, root):
 3         """
 4         :type root: TreeNode
 5         :rtype: List[int]
 6         """
 7         #1.递归法
 8         # if not root :
 9         #     return []
10 
11         # left = self.postorderTraversal(root.left)
12         # right = self.postorderTraversal(root.right)
13 
14         # return left + right + [root.val]
15 
16         #2.迭代法
17         if not root:
18             return []
19         stack = [root]
20         result = []
21 
22         while stack:
23             node = stack.pop()
24             result.append(node.val)
25             #左孩子先入栈
26             if node.left:
27                 stack.append(node.left)
28             #右
29             if node.right:
30                 stack.append(node.right)
31         # 将最终的数组翻转
32         return result[::-1]

12.迭代法:中序遍历:

  1. 处理:将元素放进result数组中
  2. 访问:遍历节点

         3.中序遍历是左中右,先访问的是二叉树顶部的节点,然后一层一层向下访问,直到到达树左面的最底部,再开始处理节点(也就是在把节点的数值放进result数组中),这就造成了处理顺序和访问顺序是不一致的。

        4.借用指针的遍历来帮助访问节点,栈则用来记录遍历过的节点,再将处理过的元素放入result数组中。

 1 class Solution(object):
 2     def inorderTraversal(self, root):
 3         """
 4         :type root: TreeNode
 5         :rtype: List[int]
 6         """
 7         #1.递归法
 8         # if not root :
 9         #     return []
10 
11         # left = self.inorderTraversal(root.left)
12         # right = self.inorderTraversal(root.right)
13 
14         # return left + [root.val] + right
15         
16         #2.迭代法
17         #迭代终止条件
18         if not root:
19             return []
20         stack = []
21         result = []
22         cur = root
23 
24         while cur or stack:
25              # 先迭代访问最底层的左子树结点
26              if cur:
27                  stack.append(cur)
28                  cur = cur.left
29              # 到达最左结点后处理栈顶节点
30              else:
31                  cur = stack.pop()
32                  result.append(cur.val)
33                  # 取栈顶元素右结点
34                  cur = cur.right
35 
36             return result

ps:记得之后看二叉树的统一迭代法

标签:遍历,TreeNode,val,self,第十四天,right,二叉树,root,left
From: https://www.cnblogs.com/wuyijia/p/17422411.html

相关文章

  • 图解LeetCode——剑指 Offer 34. 二叉树中和为某一值的路径
    一、题目给你二叉树的根节点root和一个整数目标和targetSum,找出所有从根节点到叶子节点路径总和等于给定目标和的路径。叶子节点是指没有子节点的节点。二、示例2.1>示例1:【输入】root=[5,4,8,11,null,13,4,7,2,null,null,5,1],targetSum=22【输出】[[5,4,11,2],[5,......
  • 图解LeetCode——662. 二叉树最大宽度(难度:中等)
    一、题目给你一棵二叉树的根节点root,返回树的最大宽度。树的最大宽度是所有层中最大的宽度。每一层的宽度被定义为该层最左和最右的非空节点(即,两个端点)之间的长度。将这个二叉树视作与满二叉树结构相同,两端点间会出现一些延伸到这一层的null节点,这些null节点也计入长......
  • 图解LeetCode——剑指 Offer 07. 重建二叉树
    一、题目输入某二叉树的前序遍历和中序遍历的结果,请构建该二叉树并返回其根节点。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。二、示例2.1>示例1:【输入】preorder=[3,9,20,15,7],inorder=[9,3,15,20,7]【输出】[3,9,20,null,null,15,7]2.2>示例2:【输入】pr......
  • 图解LeetCode——654. 最大二叉树(难度:中等)
    一、题目给定一个不重复的整数数组 nums。 最大二叉树 可以用下面的算法从 nums递归地构建:1>创建一个根节点,其值为 nums中的最大值。2>递归地在最大值 左边 的 子数组前缀上 构建左子树。3>递归地在最大值右边的 子数组后缀上 构建右子树。返回 nums构建的......
  • map判断是否存在某个key,以及遍历jsonobject
    if(filter.containsKey("nodeData")){JSONObjectjsonObject=(JSONObject)filter.get("nodeData");Iteratoriterator=jsonObject.keySet().iterator();while(iterator.hasNext()){Stri......
  • 代码随想录算法训练营第14天 | ● 理论基础 ● 递归遍历 ● 迭代遍历 ● 统一迭代 -
     第六章二叉树part01今日内容:  ●  理论基础●  递归遍历  ●  迭代遍历●  统一迭代   详细布置   理论基础  需要了解 二叉树的种类,存储方式,遍历方式 以及二叉树的定义  文章讲解:https://programmercarl.com/%E4%BA%8C%E5%8F%89%......
  • #yyds干货盘点# LeetCode程序员面试金典:平衡二叉树
    题目:给定一个二叉树,判断它是否是高度平衡的二叉树。本题中,一棵高度平衡二叉树定义为:一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过1。 示例1:输入:root=[3,9,20,null,null,15,7]输出:true示例2:输入:root=[1,2,2,3,3,null,null,4,4]输出:false示例3:输入:root=[]......
  • 102. 二叉树的层序遍历
    classSolution{public:vector<vector<int>>res;voidbfs(TreeNode*root){queue<TreeNode*>q;q.push(root);intlast=0;while(!q.empty()){vector<int>level;......
  • LeetCode 103. 二叉树的锯齿形层次遍历
    classSolution{public:vector<vector<int>>res;voidbfs(TreeNode*root){queue<TreeNode*>q;q.push(root);intcnt=0;while(!q.empty()){vector<int>level;......
  • 145. 二叉树的后序遍历
    /***Definitionforabinarytreenode.*structTreeNode{*intval;*TreeNode*left;*TreeNode*right;*TreeNode():val(0),left(nullptr),right(nullptr){}*TreeNode(intx):val(x),left(nullptr),right(nullptr){}*......