0
点赞
收藏
分享

微信扫一扫

LeetCode力扣~二叉树的前,中,后序遍历

题目


  • 本篇实现二叉树的前中后序遍历,对应leetCode题目如下

前序遍历: 0144.二叉树的前序遍历
后序遍历: 0145.二叉树的后序遍历
中序遍历: 0094.二叉树的中序遍历

例如前序遍历题目如下:
144. 二叉树的前序遍历
给你二叉树的根节点 root ,返回它节点值的 前序 遍历
示例 1:
输入:root = [1,null,2,3]
输出:[1,2,3]
示例 2:
输入:root = []
输出:[]
示例 3:
输入:root = [1]
输出:[1]
示例 4:
输入:root = [1,2]
输出:[1,2]
示例 5:
输入:root = [1,null,2]
输出:[1,2]
提示:
树中节点数目在范围 [0, 100] 内
-100 <= Node.val <= 100
进阶:递归算法很简单,你可以通过迭代算法完成吗?
复制代码

相关知识点


  • 满二叉树:只有度为0的结点和度为2的结点,并且度为0的结点在同一层上
  • 完全二叉树: 除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置
  • 二叉搜索树: 左子树上所有结点的值均小于它的根结点的值,右子树上所有结点的值均大于它的根结点的值,左、右子树也分别为二叉排序树
  • 平衡二叉搜索树: 一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树
  • 二叉树的存储方式:

  1. 链式存储-指针,通过指针把分布在散落在各个地址的节点串联一起
  2. 顺序存储-数组(一层一层依次存储到数组,如果父节点的数组下表是i,那么它的左孩子就是i * 2 + 1,右孩子就是 i * 2 + 2),内存是连续分布的

  • 二叉树的遍历方式:

  1. 深度优先遍历:先往深走,遇到叶子节点再往回走

  1. 前序遍历:中左右 5412678
  2. 中序遍历:左中右 1425768
  3. 后序遍历:左右中 1247865

  1. 广度优先遍历:一层一层的去遍历

  • 层次遍历(迭代法)



解题


  • 前提:Node类

class TreeNode(var `val`: Int = 0) {
var left: TreeNode? = null
var right: TreeNode? = null
}
复制代码
1. 递归法
/**
* 递归法-前序遍历
*/
fun preOrder(root: TreeNode?) {
if (root == null)
return
print(" ${root.`val`}")
preOrder(root.left)
preOrder(root.right)
}

/**
* 递归法-中序遍历
*/
fun inOrder(root: TreeNode?) {
if (root == null)
return
inOrder(root.left)
print(" ${root.`val`}")
inOrder(root.right)
}

/**
* 递归法-后序遍历
*/
fun postOrder(root: TreeNode?) {
if (root == null)
return
postOrder(root.left)
postOrder(root.right)
print(" ${root.`val`}")
}
复制代码
2. 迭代法
/**
* 迭代法-前序遍历
* 本质上是在模拟递归,因为在递归的过程中使用了系统栈,所以在迭代的解法中常用Stack来模拟系统栈
*/
fun preOrderIter(root: TreeNode?) {
if (root == null)
return
val stack = Stack<TreeNode>()
stack.push(root)
while (stack.isNotEmpty()) {
val node = stack.pop()
print(" ${node.`val`}")
if (node.right != null) {
stack.push(node.right)
}
if (node.left != null) {
stack.push(node.left)
}
}
}

/**
* 迭代法-中序遍历
*/
fun inOrderIter(root: TreeNode?) {
if (root == null)
return
var cur = root
val stack = Stack<TreeNode>()
while (stack.isNotEmpty() || cur != null) {
while (cur != null) {
stack.push(cur)
cur = cur.left
}
val node = stack.pop()
print(" ${node.`val`}")
if (node.right != null) {
cur = node.right
}
}
}

/**
* 迭代法-后序遍历
*/
fun postOrderIter(root: TreeNode?) {
if (root == null)
return
val stack1 = Stack<TreeNode>()
val stack2 = Stack<TreeNode>()
stack1.push(root)
while (stack1.isNotEmpty()) {
val node = stack1.pop()
stack2.push(node)
if (node.left != null) {
stack1.push(node.left)
}
if (node.right != null) {
stack1.push(node.right)
}
}
while (stack2.isNotEmpty()) {
print(" ${stack2.pop().`val`}")
}
}
复制代码
测试
fun preorderTraversal() {
println("--------preorderTraversal-------")
val t1 = TreeNode(1)
val t2 = TreeNode(2)
val t4 = TreeNode(4)
val t5 = TreeNode(5)
val t6 = TreeNode(6)
val t7 = TreeNode(7)
val t8 = TreeNode(8)
t5.left = t4
t5.right = t6
t4.left = t1
t4.right = t2
t6.left = t7
t6.right = t8
println("递归法:")
print("前序遍历")
preOrder(t5)
println()
print("中序遍历")
inOrder(t5)
println()
print("后序遍历")
postOrder(t5)
println()
println("迭代法:")
print("前序遍历")
preOrderIter(t5)
println()
print("中序遍历")
inOrderIter(t5)
println()
print("后序遍历")
postOrderIter(t5)
println()
}
复制代码

买三赠一,再送一道题

199. 二叉树的右视图
给定一棵二叉树,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。
示例:
输入: [1,2,3,null,5,null,4]
输出: [1, 3, 4]
解释:
1 <---
/ \
2 3 <---
\ \
5 4 <---
复制代码

  • 解题

fun _0199_rightSideView() {
println("--------_0199_rightSideView-------")
val t1 = TreeNode(1)
val t2 = TreeNode(2)
val t3 = TreeNode(3)
val t4 = TreeNode(4)
val t5 = TreeNode(5)
val t6 = TreeNode(6)
t1.left = t2
t1.right = t3
t2.right = t5
t3.right = t4
println(rightSideView(t1))
t5.left = t6
println(rightSideView(t1))
}

fun rightSideView(root: TreeNode?): List<Int> {
val res = ArrayList<Int>()
fun dfs(root: TreeNode?, depth: Int) {
var depth = depth
if (root == null)
return
if (depth == res.size)
res.add(root.`val`)
depth++
dfs(root.right, depth)//右视图就先递归右,左视图就先递归左
dfs(root.left, depth)
}
dfs(root, 0)
return res
}
复制代码
我是今阳,如果想要进阶和了解更多的干货,欢迎关注微信公众号 “今阳说” 接收我的最新文章


举报

相关推荐

0 条评论