資料結構之二叉搜尋樹(BST)
阿新 • • 發佈:2018-12-11
JavaScript實現二叉搜尋樹(BST)
- 二叉搜尋樹定義
- 二叉搜尋樹JavaScript程式碼實現
1. 二叉搜尋樹 二叉查詢樹(英語:Binary Search Tree),也稱為二叉搜尋樹、有序二叉樹(ordered binary tree)或排序二叉樹(sorted binary tree),是指一棵空樹或者具有下列性質的二叉樹:
- 若任意節點的左子樹不空,則左子樹上所有節點的值均小於它的根節點的值;
- 若任意節點的右子樹不空,則右子樹上所有節點的值均大於它的根節點的值;
- 任意節點的左、右子樹也分別為二叉查詢樹;
- 沒有鍵值相等的節點。
–(wiki百科)
2. 二叉搜尋樹程式碼實現
const BinarySearchTree = function() { let Node = function(key) { this.key = key; this.left = null; this.rigth = null; }; let root = null; this.insert = function(key) { // 向樹中插入一個新的鍵 let newNode = new Node(key); if (root === null) { root = new Node(key); } else { insertNode(root, newNode); }; const insertNode = function(node, newNode) { if (newNode.key < node.key) { if (node.left === null) { node.left = newNode; } else { // 遞迴 insertNode(node.left, newNode); } } else { if (node.rigth === null) { node.rigth = newNode; } else { insertNode(node.rigth, newNode); } } }; }; const inOrderTraverseNode = function(node, callback) { if (node !== null) { inOrderTraverseNode(node.left, callback); callback(node.key); inOrderTraverseNode(node.rigth, callback); } }; this.inOrderTraverse = function(callback) { // 通過中序遍歷遍歷所有節點, 即從小到大順序訪問節點 inOrderTraverseNode(root, callback); }; const preOrderTraverseNode = function(node, callback) { if (node !== null) { callback(node.key); preOrderTraverseNode(node.left, callback); preOrderTraverseNode(node.rigth, callback); } }; this.preOrderTraverse = function(callback) { // 先序遍歷,即優先於後代節點的順序訪問每個節點。 preOrderTraverseNode(root, callback) }; const postOrderTraverseNode = function(node, callback) { if (node !== null) { preOrderTraverseNode(node.left, callback); preOrderTraverseNode(node.rigth, callback); callback(node.key); } }; this.postOrderTraverse = function(callback) { // 後序遍歷,即先訪問節點的後代節點再訪問節點本身。 postOrderTraverseNode(root, callback); }; const minNode = function(node) { if(node) { while(node && node.left !== null) { node = node.left; } return node.key; } return null; }; this.min = function() { // 搜尋最小值 return minNode(root); }; const maxNode = function(node) { if(node) { while(node && node.rigth !== null) { node = node.right; } return node.key; } return null; }; this.max = function() { // 搜尋最大值 return maxNode(root); }; const searchNode = function(node, key) { if (node === null) { return false; } if (key < node.key) { return searchNode(node.left, key); } else if (key > node.key) { return searchNode(node.right, key); } else { return true; } }; this.search = function(key) { // 在樹中查詢一個鍵,如果節點存在,返回true,不存在,返回false return searchNode(root, key); }; const findMinNode = function(node) { while (node && node.left !== null) { node = node.left; } return node; }; const removeNode = function(node, key) { if (node === null) { return null; } if (key < node.key) { node.left = removeNode(node.left, key); return node; } else if (key > node.key) { node.right = removeNode(node.right, key); return node; } else { // key == node.key if (node.left === null && node.right ===null) { // 該節點是葉節點(沒有子節點) node = null; return node; } else if (node.left === null) { // 該節點有一個右節點 node = node.rigth; return node; } else if (node.right === null) { node = node.left; return node; } else { // 有兩個子節點 let aux = findMinNode(node.right); node.key = aux.key; node.right = removeNode(node.right, aux.key); return node; } } }; this.remove = function(key) { // 移除某個鍵 root = removeNode(root, key); }; }