遍历二叉树:
遍历的定义指顺着一条搜索路径巡防二叉树的结点,使得每个结点均被访问一次,而且仅被访问一次(又称周游)
遍历方法:
依次遍历二叉树中的三个组成部分,便是遍历了整个二叉树
L:遍历左子树
D: 访问根结点
R: 遍历右子树
若规定先左后右,则遍历二叉树就有三种情况
DLR ———— 先(根)序遍历
LDR ———— 中(根)序遍历
LRD ———— 后(根)序遍历
遍历二叉树的算法描述:
先序遍历二叉树:若二叉树为空,则空操作,否则(1)访问根结点;(2)先序遍历左子树;(3)先序遍历右子树
中序遍历二叉树:若二叉树为空,则空操作,否则(1)中序遍历左子树;(2)访问根结点;(3)中序遍历右子树
后序遍历二叉树:若二叉树为空,则空操作,否则(1)后序遍历左子树;(2)后序遍历右子树;(3)访问根结点
由二叉树的递归定义可知,遍历左子树和遍历右子树可如同遍历二叉树一样“递归”进行。
下面我们用JavaScript实现一下二叉树的遍历
给定一个二叉树对象
var root = {
id: 1,
left: {
id: 2,
left: {
id: 4,
},
right:{
id:5
}
},
right: {
id: 3,
left: {
id: 6
},
right: {
id: 7
}
}
}
递归先序遍历
var res = []
function DLR(root) {
if(root != null) {
res.push(root.id)
if(root.left) {
DLR(root.left)
}
if(root.right) {
DLR(root.right)
}
}
return res
}
console.log('递归先序遍历', DLR(root))
递归中序遍历
var res = []
function LDR(root) {
if(root != null) {
if(root.left) {
LDR(root.left)
}
res.push(root.id)
if(root.right) {
LDR(root.right)
}
}
return res
}
console.log('递归中序遍历', DLR(root))
递归后序遍历
var res = []
function LRD(root) {
if(root != null) {
if(root.left) {
LRD(root.left)
}
if(root.right) {
LRD(root.right)
}
res.push(root.id)
}
return res
}
console.log('递归后序遍历', LRD(root))
看完上面的递归遍历,下面对比一下非递归的二叉树遍历。
非递归先序遍历
就是把递归的遍历改成循环模式,将需要遍历的树放入数组arr中,在利用数组的pop()方法,返回这个大树,取出树的根,将树的右子树放入arr中,
再将树的左子树放入arr中(这样的话pop出来的就是先左后右),然后循环上面操作,pop arr数组,取出根,然后右子树push arr中, 左子树
push arr中。。。循环
function DLR(root) {
var res = [] , arr =[]
if (root != null){
arr.push(root)
}
while (arr.length > 0) {
var temp = arr.pop()
res.push(temp.id)
if(temp.right){ // 先放右子树再放左子树 取出来的时候才是先左后右
arr.push(temp.right)
}
if(temp.left){
arr.push(temp.left)
}
}
return res
}
console.log('非递归先序遍历', DLR(root))
非递归中序遍历
先把左边的,全部放进arr再输出
function LDR(root) {
var res = [] , arr =[]
while (true){
while (root != null){
arr.push(root)
root = root.left
}
//终止条件:最后树遍历完了自然就结束
if(arr.length===0) {
break;
}
let temp = arr.pop()
res.push(temp.id)
root = temp.right
}
return res
}
console.log('非递归中序遍历', LDR(root))
非递归后序遍历
其实就是先根右左(和先序方法一样) 然后在反过来
function LRD(root) {
var res = [] , arr =[]
if (root != null){
arr.push(root)
}
while (arr.length > 0) {
var temp = arr.pop()
res.push(temp.id)
if(temp.left){
arr.push(temp.left)
}
if(temp.right){
arr.push(temp.right)
}
}
return res.reverse()
}
console.log('非递归后序遍历', LRD(root))