1. 程式人生 > 其它 >JS中的二叉搜尋樹

JS中的二叉搜尋樹

技術標籤:資料結構js資料結構二叉搜尋樹

程式碼封裝:

//封裝二叉搜尋樹
        function BinarySearchTree(){
            //節點
            function Node(key){
                this.key = key;
                this.left = null;
                this.right = null;
            }
            //屬性
            this.root = null;

            //方法
            //插入節點:給使用者呼叫的方法
BinarySearchTree.prototype.insert = function (key){ //1.根據key建立節點 var newNode = new Node(key); //2.判斷根節點是否有值 if(this.root == null){ this.root = newNode; }else{ this.insertNode
(this.root,newNode) } } //內部插入方法 BinarySearchTree.prototype.insertNode = function(node,newNode){ if(newNode.key < node.key){ //向左查詢 //如果左節點為空 if(node.left == null){ node.
left = newNode; }else{ //如果左節點不為空,遞迴查詢 this.insertNode(node.left,newNode); } }else{ //向右查詢 //如果右節點為空 if(node.right == null){ node.right = newNode; }else{ this.insertNode(node.right,newNode); } } } //樹的遍歷 //1.先序遍歷 BinarySearchTree.prototype.preOrderTraversal = function(handler){ this.preOrderTraversalNode(this.root, handler); } BinarySearchTree.prototype.preOrderTraversalNode = function(node,handler){ if(node != null){ //1.處理經過的節點 handler(node.key); //2.處理經過的節點的左子節點 this.preOrderTraversalNode(node.left,handler); //3.處理經過的節點的右子節點 this.preOrderTraversalNode(node.right,handler); } } //中序遍歷 BinarySearchTree.prototype.midOrderTraversal = function(handler){ this.midOrderTraversalNode(this.root, handler); } BinarySearchTree.prototype.midOrderTraversalNode = function(node,handler){ if(node != null){ //1.處理經過的節點的左子節點 this.midOrderTraversalNode(node.left,handler); //2.處理經過的節點 handler(node.key); //3.處理經過的節點的右子節點 this.midOrderTraversalNode(node.right,handler); } } //後序遍歷 BinarySearchTree.prototype.postOrderTraversal = function(handler){ this.postOrderTraversalNode(this.root, handler); } BinarySearchTree.prototype.postOrderTraversalNode = function(node,handler){ if(node != null){ //1.處理經過的節點的左子節點 this.postOrderTraversalNode(node.left,handler); //2.處理經過的節點的右子節點 this.postOrderTraversalNode(node.right,handler); //3.處理經過的節點 handler(node.key); } } //尋找最大值 BinarySearchTree.prototype.max = function(){ //1.獲取根節點 //2.依次向右不斷的查詢,直到節點為null var node = this.root; var key = null; while(node !== null){ key = node.key; node = node.right; } return key; } //尋找最小值 BinarySearchTree.prototype.min = function(){ var node = this.root; var key = null; //2.依次向右不斷的查詢,直到節點為null while(node !== null){ key = node.key; node = node.left; } return key; } BinarySearchTree.prototype.findMaxNode = function(node){ //1.獲取根節點 //2.依次向右不斷的查詢,直到節點為null var parent = null; var current = node; while(1){ parent = current current = current.right; if(current.right === null){ break; } } return [current,parent]; } //搜尋某一個key BinarySearchTree.prototype.search = function (key){ //1.獲取根節點 var node = this.root; //2.迴圈搜尋key while(node!= null){ if(key < node.key){ node = node.left; }else if(key > node.key){ node = node.right; }else{ return true; } } return false; } //刪除節點 BinarySearchTree.prototype.remove = function (key){ //1.尋找我們要刪除的節點 //1.1定義變數,儲存資訊 var current = this.root; var parent = null; var isLeftChild = true; //1.2開始尋找刪除的節點 while(current.key != key){ parent = current; if(key < current.key){ isLeftChild = true; current = current.left; }else{ isLeftChild = false; current = current.right; } //如果已經找到了最後一個節點,依然沒找到 if(current == null){ return false; } } //2.根據對應的情況,刪除節點 //找到了current.key === key if(current.left == null && current.right == null){ //2.1刪除的節點是葉子節點 //2.1.1刪除的是隻有一個節點的根節點 if(current == this.root){ this.root = null; }else{ if(isLeftChild){ parent.left = null; }else{ parent.right = null; } } }else if(current.left != null && current.right != null){ //2.2刪除的節點有兩個子節點 var [max,maxParent] = this.findMaxNode(current.left); console.log(max); console.log(parent); if(isLeftChild){ parent.left = max; if(max!==current.left){ parent.left.left = current.left; maxParent.right = null; } parent.left.right = current.right; }else{ parent.right = max; if(max!==current.left){ parent.right.left = current.left; maxParent.right = null; } parent.right.right = current.right; return; } }else{ //2.3刪除的節點有一個子節點 if(current === this.root){ //2.3.1刪除節點的是隻有一個子節點的根節點 if(isLeftChild){ this.root = current.left; }else{ this.root = current.right; } }else if(current.left == null){ //2.3.2刪除節點的左子節點為空 //要刪除的節點是父節點的左子節點 if(isLeftChild){ parent.left = current.right; }else{ //要刪除的節點是父節點的右子節點 parent.right = current.right } }else{ //2.3.2刪除節點的右子節點為空 //要刪除的節點是父節點的左子節點 if(isLeftChild){ parent.left = current.left; }else{ //要刪除的節點是父節點的右子節點 parent.right = current.left } } } } }