理论基础
二叉树是一种基础数据结构,在算法面试中都是常客,也是众多数据结构的基石。
本篇我们介绍了二叉树的种类、存储方式、遍历方式以及定义,比较全面的介绍了二叉树各个方面的重点
递归遍历
掌握二叉树三种递归遍历
思路:
-
确定递归函数的参数和返回值: 确定哪些参数是递归的过程中需要处理的,那么就在递归函数里加上这个参数, 并且还要明确每次递归的返回值是什么进而确定递归函数的返回类型。
-
确定终止条件: 写完了递归算法, 运行的时候,经常会遇到栈溢出的错误,就是没写终止条件或者终止条件写的不对,操作系统也是用一个栈的结构来保存每一层递归的信息,如果递归没有终止,操作系统的内存栈必然就会溢出。
-
确定单层递归的逻辑: 确定每一层递归需要处理的信息。在这里也就会重复调用自己来实现递归的过程。
代码实现:
class TreeNode {
constructor(val, left, right) {
this.val = (val === undefined ? 0 : val)
this.left = (left === undefined ? null : left)
this.right = (right === undefined ? null : right)
}
}
//前序遍历 递归法
function preorderTraversal (root) {
let res = []
const dfs = function (root) {
if (root === null) return
res.push(root.val)
dfs(root.left)
dfs(root.right)
}
dfs(root)
return res
}
//中序遍历
function inorderTraversal (root) {
let res = []
const dfs = function (root) {
if (root === null) return
dfs(root.left)
res.push(root.val)
dfs(root.right)
}
dfs(root)
return res
}
//后序遍历
function postorderTraversal (root) {
let res = []
const dfs = function (root) {
if (root === null) return
dfs(root.left)
dfs(root.right)
res.push(root.val)
}
dfs(root)
return res
}
迭代遍历
代码实现
//前序遍历 迭代法
var preorderTraversal = function (root, res = []) {
if (!root) return res;
const stack = []
stack.push(root)
let node = null
while (stack.length) {
node = stack.pop()
res.push(node.val)
node.right && stack.push(node.right)
node.left && stack.push(node.left)
}
return res
};
//中序遍历 迭代法
var inorderTraversal = function (root, res = []) {
if (!root) return res;
const stack = []
let node = root
while (node != null || stack.length) {
if (node !== null) {
stack.push(node)
node = node.left
} else {
//中
node = stack.pop();
res.push(node.val)
//右
node = node.right
}
}
return res
};
//后序遍历 迭代法
var postorderTraversal = function (root, res = []) {
if (!root) return res;
const stack = []
stack.push(root)
let node = null
while (stack.length) {
node = stack.pop()
res.push(node.val)
node.left && stack.push(node.left)
node.right && stack.push(node.right)
}
res = res.reverse()
return res
};
统一迭代
代码实现
//统一迭代法
//前序
var preorderTraversal = function (root, res = []) {
const stack = [];
if (root) stack.push(root)
while (stack.length) {
const node = stack.pop()
if (!node) {
res.push(stack.pop().val)
continue
}
if (node.right) stack.push(node.right)
if (node.left) stack.push(node.left)
stack.push(node)
stack.push(null)
}
return res
}
//中序 左中右
var inorderTraversal = function (root, res = []) {
const stack = [];
if (root) stack.push(root)
while (stack.length) {
const node = stack.pop()
if (!node) {
res.push(stack.pop().val)
continue
}
if (node.right) stack.push(node.right)
stack.push(node)
stack.push(null)
if (node.left) stack.push(node.left)
}
return res
}
//后序 左右中
var inorderTraversal = function (root, res = []) {
const stack = [];
if (root) stack.push(root)
while (stack.length) {
const node = stack.pop()
if (!node) {
res.push(stack.pop().val)
continue
}
stack.push(node)
stack.push(null)
if (node.right) stack.push(node.right)
if (node.left) stack.push(node.left)
//中 空 右 左
}
return res
}
总结:
这一部分练习不算很困难 但仍然需要多复习,加强理论知识的巩固