前言
今天我们来聊聊二叉树这种数据结构并且实现它的三种遍历
二叉树
二叉树(Binary tree)是树形结构的一个重要类型。许多实际问题抽象出来的数据结构往往是二叉树形式,即使是一般的树也能简单地转换为二叉树,而且二叉树的存储结构及其算法都较为简单,因此二叉树显得特别重要。二叉树特点是每个节点最多只能有两棵子树,且有左右之分。
二叉树是n个有限元素的集合,该集合或者为空、或者由一个称为根(root)的元素及两个不相交的、被分别称为左子树和右子树的二叉树组成,是有序树。当集合为空时,称该二叉树为空二叉树。在二叉树中,一个元素也称作一个节点 。
注意:
1.空树也可称为二叉树
2.非空树必须由根结点,左子树,右子树组成,且左右子树都是二叉树
遍历
1.先序遍历--根左右
[我们以力扣144为例](144. 二叉树的前序遍历 - 力扣(LeetCode))
结果为:[1,2,3]
用递归的方法:
function preorderTraversal(root){
let res=[];
function preorder(node){
if(node){
res.push(node.val)
preorder(node.left)
proorder(node.right)
}
}
preorder(root)
return res;
}
递归就是自己调用自己,第4行先进行判断是否为空,若不为空则把该结点放入空数组,递归左结点,右结点。
迭代法:
var preorderTraversal=function (root){
if(root==null) return []
const res=[]
const stack=[]
stack.push(root)
while(stack.length){
const cur=stack.pop()
res.push(cur.val)
if(cur.right){
stack.push(cur.right)
}
if(cur.left){
stack.push(cur.left)
}
}
return res
}
我们先假设有这样一个树
先序遍历的结果是:[1,2,4,5,3,6]
用栈怎么解决呢?我们可以这样:结点1先入栈,判断栈是否有值如果有出栈,判断如果结点1存在右结点,右结点3入栈,左结点2入栈。结点2出栈,判断如果存在右结点,右结点5入栈,左结点4入栈。结点4出栈判断是否有右结点,没有继续出栈结点5, 结点3出栈,有右结点6,右结点入栈,右结点6出栈
2.中序遍历 ---左根右
结果·:[4,2,5,1,3,6]
递归法:
function inorderTraversal(root){
const res=[]
function inorder(node){
inorder(node.left)
res.push(node.val)
inorder(node.right)
}
inorder(root);
return res;
}
迭代:
var inorderTraversal = function(root) {
if(root == null) return []
let res = []
let stack = []
let cur = root
while(stack.length || cur){
while(cur){
stack.push(cur)
cur = cur.left
}
cur = stack.pop()
res.push(cur.val)
cur = cur.right
}
return res
}
这里有点难度:还是上面那个树。先读到根节点1入栈,让一个变量存放根结点的左结点,此时为2,将2入栈,这变量为4,4没有左结点出栈,2出栈,5入栈,没有左结点,5出栈,1出栈,1有右结点,3入栈,3没有左结点出栈,3有右结点6,6出栈,6没有子结点,结束。
后序遍历---左右根
结果:[4,5,2,6,3,1]
递归:
function postorderTraversal(root){
const res=[];
function postorder(node){
if(node){
postorder(node.left);
postorder(node.right);
res.push(node.val);
}
}
postorder(root)
return res;
}
迭代:
var postorderTraversal = function(root) {
if(!root) return []
const res = [];
const stack=[];
stack.push(root)
while(stack.length){
const cur=stack.pop()
res.unshift(cur.val)
if(cur.left){
stack.push(cur.left)
}
if(cur.right){
stack.push(cur.right)
}
}
return res;
}
后序遍历和前序遍历类似,还是那棵树:根结点1入栈,1出栈,左右结点分别入栈,结点3出栈,结点3有右子结点6入栈,6没有左右结点出栈,2接着出栈,4,5入栈,5没有子结点出栈,4没有子结点出栈.出栈元素全都放入数组头部,得到最后结果。
总结
今天我们聊了有关二叉树的知识并且刷了几道力扣算法题,最后希望大家好好学习,天天向上吧。