遍歷二叉樹:
遍歷的定義指順著一條搜尋路徑巡防二叉樹的結點,使得每個結點均被訪問一次,而且僅被訪問一次(又稱周遊)
複製程式碼
遍歷方法:
依次遍歷二叉樹中的三個組成部分,便是遍歷了整個二叉樹
複製程式碼
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))