前言
一、创建数结构(类),测试数据
//创建二叉树
class tree{
constructor(val,left,right){
this.val = val;
this.left = left;
this.right = right;
}
}
//模拟数据
let q7 ,q8,q9,q10,q11,q12,q13,q14 = null;
let q6 = new tree(7,q13,q14);
let q5 = new tree(6,q11,q12);
let q4 = new tree(5,q9,q10);
let q3 = new tree(4,q7,q8);
let q2 = new tree(3,q5,q6);
let q1 = new tree(2,q3,q4);
let q = new tree(1,q1,q2);
二、前序遍历
1.递归
递归的实现就是:每一次递归调用都会把函数的局部变量、参数值和返回地址等压入调用栈中,然后递归返回的时候,从栈顶弹出上一次递归的各项参数,所以这就是递归为什么可以返回上一层位置的原因。
定义一个递归函数,循环遍历子节点
递归结束条件为子节点为空
先写入根元素
如果有左子树,先写入左子树根元素,然后再判断有无左子树,如果有就继续【3,4】步骤
如果没有左子树了,就写入右子树元素,然后判断有无右子树,继续【3,5步骤】
【1】先写入根元素[1]
【2】传入左子树[2,4,5],写入根元素[2]
【3】传入左子树[4],写入[4]
【4】没有左子树了,写入右子树[5]
【5】右子树递归调用……
function preFunction(root){
var arr = []
const tempPre = (node,arr)=>{
if(!node) return
arr.push(node)
if(node.left) tempPre(node.left,arr)
if(node.right) tempPre(node.right,arr)
}
tempPre(root,arr)
return arr
}
let p = preFunction(q) //先序-递归
2.迭代
使用栈来存储下次要访问的结构,前序遍历顺序为左、中、右
每次把根节点压入栈中,
迭代,当栈中有元素时,就出栈,访问节点值
然后子树继续压入栈中,再弹出访问节点值
因为栈是后进先出,所以先写右子树再写左子树
【1】先放入栈中整个树,访问值1
【2】右子树[3,6,7]放入栈中,左子树[2,4,5]再放入栈中
【3】先弹出[2,4,5],然后访问值2,再访问其左子树4,最后没有左子树了只有右子树5
【4】最后再弹出右子树依如上有顺序访问
function preDeep(node){
let arr = [], res = []
let head = node
arr.push(head)
while(arr.length){
head = arr.pop()
res.push(head)
// 依次推入右边、左边节点
// 为什么先推入右因为我们使用的是pop、
if(head.right) arr.push(head.right)
if(head.left) arr.push(head.left)
}
return res
}
let a = preDeep(q); //先序-迭代
三、中序遍历
1.迭代
function orderDeep(root) {
const res = []
const arr = []
if (!root) return []
let cur = root
arr.push(cur)
while (arr.length) {
if (cur.left) {
arr.push(cur.left)
cur = cur.left
} else {
const pop = arr.pop()
res.push(pop)
if (pop.right) {
arr.push(pop.right)
cur = pop.right
}
}
}
return res
},
let b = orderDeep(q)
2.递归
function orderFunction(root) {
// 中序遍历、左、根、右
const res = []
const traversal = (node, arr) => {
if (!node) return
// 先左
if (node.left) traversal(node.left, arr)
arr.push(node)
// 后右
if (node.right) traversal(node.right, arr)
}
traversal(root, res)
return res
},
let p1 = orderFunction(q)
四、后序遍历
1.递归
function endFunction(root) {
let arr=[]
let endTempPre = (node,arr)=>{
if(!node) return []
if(node.left) endTempPre(node.left,arr)
if(node.right) endTempPre(node.right,arr)
arr.push(node.val)
}
endTempPre(root,arr)
return arr
}
let p2 = endFunction(q); //后续
2.迭代
/* 本质和前序遍历相同
* 后序遍历= reverse(preOrderTraversal(从右开始))
* 正常前序是中-左-右,后序遍历 = reverse(中-右-左)
*/
function endDeep(root){
if(!root) return []
let arr=[],res=[],cur=root
arr.push(cur)
while(arr.length){
cur = arr.pop()
res.unshift(cur.val)
if(cur.left) arr.push(cur.left)
if(cur.right) arr.push(cur.right)
}
return res
}