記得一開始學習數據結構用的是c語言實現,學了這麼久前端就想用JavaScript來實現一下,順便複習下數據結構。前端
先來了解下什麼是排序二叉樹,排序二叉樹是具備如下特色的二叉樹node
下面咱們用代碼實現一波git
首先是樹的結構和根節點github
var Node = function(key){//節點結構 this.left = null this.right = null this.key = key }
var root = null //根節點複製代碼
二叉樹的插入,基本過程是比較要插入的數和當前節點的值大小,按照排序二叉樹的特色,左邊的值永遠小於右邊bash
var insertNode = function(node,newNode){ if(node.key > newNode.key){//要插入的值小於當前節點,左子樹遍歷 if(node.left === null){ node.left = newNode return }else{ insertNode(node.left,newNode) } }else if(node.key <= newNode.key){//要插入的值小於當前節點,右子樹遍歷 if(node.right === null){ node.right = newNode }else{ insertNode(node.right,newNode) } } }
複製代碼
插入成功後咱們分別來實現排序二叉樹的前序,中序和後序遍歷數據結構
前序遍歷是先訪問根節點,然後是左右節點學習
中序遍歷先訪問左節點,然後是根節點和右節點ui
後序遍歷則先訪問左右節點,最後是根節點this
代碼以下spa
var inOrderTraverseNode = function(node,callback){//中序遍歷 if(node !== null){ inOrderTraverseNode(node.left) console.log(node.key) inOrderTraverseNode(node.right) } }
var preOrderTraverseNode = function(node,callback){//前序遍歷 if(node !== null){ console.log(node.key) preOrderTraverseNode(node.left) preOrderTraverseNode(node.right) } }
var afterOrderTraversNode = function(node,callback){//後序遍歷 if(node !== null){ afterOrderTraversNode(node.left) afterOrderTraversNode(node.right) console.log(node.key) } }
複製代碼
尋找二叉樹的最大值和最小值,這一部分根據排序二叉樹的特色很快就能知道,最大值在最右邊的葉子節點,最小值處於最左邊的葉子節點
var Max = function(node){//最大值 if(node.right !== null){ maxNum = Max(node.right) }else{ return node.key } return maxNum }
var Min = function(node){//最小值 if(node.left !== null){ minNum = Min(node.left) }else{ return node.key } return minNum }複製代碼
尋找排序二叉樹中的指定值,也很簡單,以根節點爲界,比左邊小到左邊找,比右邊小去右邊
var Search = function(node,key){//尋找指定值 if(node.key === key){ return true }else{ if(key < node.key && node.left !=null){ return Search(node.left,key) }else if(key > node.key && node.left !=null){ return Search(node.right,key) }else{ return false } } }複製代碼
最麻煩的是刪除節點的操做,這裏須要分三種狀況,刪除節點無子樹,刪除節點爲單子樹,刪除節點有兩個子樹,
無子樹最簡單,直接刪
if(node.left === null && node.right === null){ node = null return node }複製代碼
有單子樹的:好比下圖(畫的有點醜。。。),如今我要刪掉3,
就會變成
代碼實現以下
else if(node.left !== null && node.right === null){ node = node.left return node }else if(node.left === null && node.right !== null){ node = node.right return node }複製代碼
最後是刪除有兩個子樹的節點,爲了維持咱們排序二叉樹的性質,首先咱們找到要刪除節點的右字樹的最小值,根據排序二叉樹的特色,找到的最小值一定大於要刪除節點的左子樹的全部值,由於找到的值爲右節點的最小值,因此小於要刪除節點的右子樹的全部值,咱們將找到的最小值代替要刪除的值,最後刪掉一開始找到的最小值的節點,基本過程就至關於替換了要刪除節點的值。
下圖,我要刪掉3
按照上面的思想,找到4代替3,而後刪掉一開始找到的4所在的節點
依舊知足排序二叉樹的特色
else if(node.left !== null && node.right !== null){ var minNode = finMinNode(node.right) node.key = minNode.key node.right = Remove(node.right,minNode.key) return node }複製代碼
到這裏排序二叉樹的基本功能都實現了