標籤:資料庫 type 支援 .net 電腦科學 switch water tno parent
我覺得這社會上,也不差錢好多人,可能好多人也不差權力,但是我覺得能得到這種滿足的也不多。 –郭小平<臨汾紅絲帶學校校長>
? 樹是電腦科學中經常用到的一種資料結構。樹是一種非線性資料結構,以分層的方式儲存資料。是被用來儲存具有層級關係或有序的資料,比如檔案系統中的檔案。
二叉樹
二叉樹,每個節點最多有兩個子樹的樹結構。二叉樹是一種特殊的樹,也是一個連通的無環圖。
二叉尋找樹
? 二叉尋找樹是一種特殊的二叉樹,其相對較小的值儲存在左節點中,較大的值儲存在右節點中。這一特性使其尋找效率很高。
實現二叉尋找樹
? 如果待插入節點小於(大於)當前節點,且當前節點的左(右)節點為null,則將待插入節點插入到當前節點的左(右)節點位置上,結束迴圈;否則,將當前節點的左(右)節作為當前節點繼續下次迴圈。
/** * 節點定義 * @param data 資料 * @param left 左子樹 * @param right 右子樹 * @constructor */function Node(data, left, right) { this.data = data; this.left = left; this.right = right;}Node.prototype.show = function() { return this.data;};/** * 二叉尋找樹定義 * @constructor */function BST() { this.root = null;}/** * 插入節點 * @constructor */BST.prototype.insert = function(data) { // 待插入節點 var node = new Node(data, null, null); if(this.root === null) { this.root = node; } else { var currentNode = this.root; var parent; while(true) { parent = currentNode; // 待插入節點小於當前節點 if(data < currentNode.data) { // 將其左子樹作為當前節點 currentNode = currentNode.left; if(currentNode === null) { parent.left = node; break; } }else { // 將其右子樹作為當前節點 currentNode = currentNode.right; if(currentNode === null) { parent.right = node; break; } } } } return this; // 支援鏈式調用};
- 中序:先訪問左子樹,再訪問根節點,最後訪問右字數;以升序訪問BST上所有節點;(左==>根==>右)
- 先序:先訪問根節點,然後以同樣方式訪問左子樹和右子樹;(根==>左==>右)
- 後序:先訪問葉子節點,從左子樹到右子樹,再到根節點。(左==>右==>根)
BST.prototype.order = function(node, type) { switch (type) { case "inorder": // 中序 if(node != null) { /*左==>根==>右*/ this.order(node.left, type); console.log(node.show()); this.order(node.right, type); } break; case "preorder": // 先序 if(node != null) { /*根==>左==>右*/ console.log(node.show()); this.order(node.left, type); this.order(node.right, type); } break; case "postorder": // 後序 if(node != null) { /*左==>右==>根*/ this.order(node.left, type); this.order(node.right, type); console.log(node.show()); } break; }};
測試
var bst = new BST();bst.insert(32).insert(11).insert(2) .insert(13).insert(75) .insert(66).insert(88);bst.order(bst.root, "inorder"); // 中序bst.order(bst.root, "preorder"); // 先序bst.order(bst.root, "postorder"); // 後序
查詢最小值和最大值
- 最小值:遍曆左子樹,直到找到最後一個節點;
- 最大值:遍曆右子樹,直到找到最後一個節點。
/** * 擷取最小值:左子樹的最後一個節點 */BST.prototype.getMin = function(node) { var currentNode = node || this.root; while(currentNode.left !== null) { currentNode = currentNode.left; } return currentNode;};/** * 擷取最小值:右子樹的最後一個節點 */BST.prototype.getMax = function(node) { var currentNode = node || this.root; while(currentNode.right !== null) { currentNode = currentNode.right; } return currentNode;};console.log(bst.getMin().data); // 2console.log(bst.getMax().data); // 88
尋找某節點
/** * 尋找某節點 * @param data 資料 */BST.prototype.find = function(data) { var currentNode = this.root; while(currentNode !== null) { if(data === currentNode.data) { return currentNode; } currentNode = (data < currentNode.data) ? currentNode.left : currentNode.right; } return null;};console.log(bst.find(66)); // Node { data: 66, left: null, right: null }console.log(bst.find(99)); // null
刪除節點
- 如果待刪除節點為葉子節點,則直接刪除它;
- 如果待刪除節點只有一個子節點,則直接將待刪除節點的父節點指向其子節點;
- 如果待刪除節點包含兩個子節點,我們選擇右子樹上的最小值建立一個臨時節點,然後複製到待刪節點,然後刪除最小值節點。
/** * 移除指定資料節點 * @param data */BST.prototype.remove = function(node, data) { node = node || this.root; if(data === null) { // 待刪除節點不存在 return node; } if(node.data === data) { // 無子節點 if(node.left === null && node.right === null) { return null; } // 只有右節點,無左節點 if(node.left === null) { return node.right; } // 只有左節點,無右節點 if(node.right === null) { return node.left; } // 存在兩個節點 var minNode = this.getMin(node.right); console.log(minNode); node.data = minNode.data; node.right = this.remove(node.right, minNode.data); }else if( node.data > data) { node.left = this.remove(node.left, data); }else if( node.data < data){ node.right = this.remove(node.right, data); } return node;};
總結
? 樹,在電腦科學中體現的特別多 。如,我們熟悉的DOM樹,資料庫底層經常用到的B樹等等。樹能很好的保證字典序,儲存詞典的空間壓縮率高, 能做首碼搜尋。抽象地說,基本上有序列的地方就可以應用樹,因為樹結構即是一種序列索引結構。
JavaScript資料結構-樹