之前只用c語言實現過二叉樹,最近在面試,也是為了鍛鍊自己的js水平,今天用了js實現排序二叉樹,也算是對之前二叉樹相關知識的乙個回顧。
什麼是二叉排序樹(bst)
二叉排序樹也被稱為二叉搜尋樹,二叉排序樹是具有下列性質的二叉樹(可以是空樹):
(1)若左子樹不空,則左子樹上所有節點的值均小於它的根節點的值;
(2)若右子樹不空,則右子樹上所有節點的值均大於它的根節點的值;
(3)左、右子樹也分別為二叉排序樹;
(4)沒有鍵值相等的節點。
具體演算法的思路與實現
1.定義二叉樹相關的資料結構
排序二叉樹是二叉樹的乙個特例,因此它也具有二叉樹的資料結構,我們可以使用定義二叉樹的方法來定義它。
function
node
(val)
function
binarytree
(arr)
)return
this
}
2.插入結點
我們使用insert()方法來插入結點,insertnode()方法是insert()方法的關鍵實現。插入結點的方法如下:
通過遞迴依次將待插入的節點與排序二叉樹的部分節點進行大小比較。從根節點開始,遵循左子節點小於當前節點,右子節點大於當前節點的規則進行遞迴插入。比如:我們需要插入乙個比父親結點小的元素,如果父親結點左孩子為空,那麼我們把它直接插入到父親結點的左邊;否則,我們只能在父親結點的左孩子的左孩子進行插入,以此類推。這段話可能有點繞口,下面解合**以及注釋應該就一目了然了。
binarytree.prototype.
insert
=function
(val)
else
}binarytree.prototype.
insertnode
=function
(node, newnode)
else
}else
else
}}
3.三種遍歷方式
常見的三種遍歷方式為:前序遍歷、中序遍歷、後序遍歷。層次遍歷以及上述方法的非遞迴實現在更新了棧和佇列的資料結構之後再去講,這裡先忽略。
1.前序遍歷的操作過程如下:
如果二叉樹為空樹,則什麼都不做,否則。
(1)訪問根結點。
(2)前序遍歷左子樹。
(3)前序遍歷右子樹。
作用:前序遍歷可以用來複製二叉樹,每個結點只用訪問一遍,效率非常的高。
對應的**如下:
binarytree.prototype.
preorder
=function
(node)
}
2.中序遍歷的操作過程如下:
如果二叉樹為空樹,則什麼都不做,否則。
(1)中序遍歷左子樹。
(2)訪問根節點。
(3)中序遍歷右子樹。
作用:中序遍歷之後會得到乙個公升序排列的序列,因此它可以用來對無重複資料的陣列進行排序,時間複雜度為o(logn)。
對應的**如下:
binarytree.prototype.
inorder
=function
(node)
}
3.後序遍歷的操作過程如下:
如果二叉樹為空樹,則什麼都不做,否則。
(1)後序遍歷左子樹。
(2)後序遍歷右子樹。
(3)訪問根節點。
作用:作業系統中的相關的檔案訪問操作,因為它很容易計算路徑。
對應**如下:
binarytree.prototype.
postorder
=function
(node)
}
4.查詢二叉樹中的最小與最大結點
這個其實非常好理解,因為二叉排序樹總是父親結點的值大於左孩子的值,且小於右孩子的值,那麼當我們查詢最大或最小值時,只需要一直沿著一側查詢就可以了。**如下,也非常的簡單:
// 查詢二叉樹中的最小值結點
binarytree.prototype.
getminnode
=function
(node)
return p
}// 查詢二叉樹中的最大值結點
binarytree.prototype.
getmaxnode
=function
(node)
return p
}
5.查詢二叉樹中的是否存在值為num的某個結點
這個也是利用了二叉排序樹的特效,當num比當前結點值小時,只需要向左側查詢,反之向右側查詢即可,與第4點類似,**如下:
// 查詢二叉樹中是否存在值為num的某個結點
binarytree.prototype.
searchnode
=function
(node, num)
else
if(num > node.val)
else
}else
}
6.刪除值為val的結點
這個是二叉排序樹的操作中比較難的乙個,思路是:先在二叉樹中找到值為val的結點,如果沒找到,則返回false,如果找到了,則進行刪除,並且返回true。
刪除操作需要分四種情況考慮:
1.是葉子結點:這個非常簡單,找到結點直接刪除即可,它的刪除不會改變二叉樹其他結點的結構。
2.只有左孩子:這個也比較簡單,只需要找到該結點,並且將該結點node的父結點指向node.left即可。
3.只有右孩子:與第2點類似,只是換成了right,這裡不多贅述。
4.既有左孩子又有右孩子:這個就是比較難的點了,因為我們對該結點刪除會改變其餘結點的結構,我們使用的方法是:找到這個結點的最小後代結點aux,將aux的值與node進行交換,並刪除最小結點。
**如下:
binarytree.prototype.
remove
=function
(node, val)
if(val < node.val)
else
if(val > node.val)
else
if(node.right ===
null)if
(node.left ===
null
)// 以上條件都不符合,即存在左孩子和右孩子
let aux =
this
.getminnode
(node.right)
node.val = aux.val // 最小結點的值和node進行交換
node.right =
this
.remove
(node.right, aux.key)
// 刪除最小結點
return node
}}
結語 二叉樹建立以及遍歷
題目描述 編乙個程式,讀入使用者輸入的一串先序遍歷字串,根據此字串建立乙個二叉樹 以指標方式儲存 例如如下的先序遍歷字串 abc de g f 其中 表示的是空格,空格字元代表空樹。建立起此二叉樹以後,再對二叉樹進行中序遍歷,輸出遍歷結果。輸入描述 輸入包括1行字串,長度不超過100。輸出描述 可能...
C 二叉樹的建立以及遍歷
在筆試面試的過程中,二叉樹也是難點之一,考的也是比較多的。我也是被這個問題給難倒過,不能在乙個地方摔兩次啊!雖然這個東西第一次寫出來了,可是如果長時間不看不寫不用,還是很容易忘記的。溫故而知新,老子還是很厲害的啊,要謹記老子的話了。廢話不多說,直接上 吧!還是一樣在vc6.0上除錯過的。includ...
二叉樹的建立以及遍歷C C
一 二叉樹的定義 二叉樹 binary tree 是個有限元素的集合,該集合或者為空,或者由乙個稱為根 root 的元素及兩個不相交的 分別被稱為左子樹和右子樹的二叉樹組成。當集合為空時,稱該二叉樹為空二叉樹,在二叉樹中,乙個元素也成為乙個節點。二 二叉樹的資料結構 下面為二叉樹鏈式儲存結構的定義 ...