基本知识
二叉树:二叉树的所有结点的最大度数为2; 二叉搜索树:又称为二叉排序树,根节点与其左右子结点的满足以下关系:左子结点<根结点<右子结点; 完全二叉树:除最后一层外,其它各层达到该层最大结点数;结点为n的完全二叉树深度为log2(n+1); 第i层的最大结点数:2^(i-1); 深度为h的最大最大总节点数:2^h-1;
function BinarySearchTree() { /** * 二叉搜索树的初始化 */ var root = null; var Node = function (value) { this.value = value; this.left = null; this.right = null; } // var Node = (value) => { // this.value = value; // this.left = null; // this.right = null; // } /** * 插入键值到binarySearchTree */ this.insert = function (value) { var newNode = new Node(value); if (root === null) { root = newNode; } else { insertNode(root, newNode); } } /** * 插入子结点 * @param {Node} node * @param {Node} newNode */ var insertNode = function (node, newNode) { if (node.value > newNode.value) { if (node.left === null) { node.left = newNode; } else { insertNode(node.left, newNode); } } else { if (node.right === null) { node.right = newNode; } else { insertNode(node.right, newNode); } } } /** * 移除结点 */ this.remove = function (value) { root = removeNode(root, value); } /** * 递归寻找并移除结点 * @param {Node} node * @param {Node.value} value 需要移除的结点的值 */ var removeNode = function (node, value) { if (node === null) { return null; } if (value < node.value) { node.left = removeNode(node.left, value); } else if (value > node.value) { node.right = removeNode(node.right, value); } else { //该结点为叶子结点 if (node.left === null && node.rigth === null) { node = null; } //该结点有一个子结点 else if (node.left === null) { node = node.right; // node.right = null; } else if (node.right === null) { node = node.left; // node.left = null; } //该结点有两个子结点,此时可以取左子树中的最大值代替根结点;当然也可以取右子树中的最小值代替根结点 else if (node.left != null && node.right != null) { var temp = minRightNode(node.right); node.value = temp.value; node.right = removeNode(node.right, temp.value); } } return node; } var minRightNode = function (node) { if (node) { while (node && node.left != null) { node = node.left; } return node; } return null; } /** * 先序遍历binarySearchTree * @param {Function} callback */ this.preOrderTraverse = function (callback) { console.log("先序遍历:"); preOrderTraverseNode(root, callback); } /** * 递归实现先序遍历 * @param {Node} node * @param {Fucntion} callback */ var preOrderTraverseNode = function (node, callback) { if (node != null) { callback(node); preOrderTraverseNode(node.left, callback); preOrderTraverseNode(node.right, callback); } } /** * 非递归先序遍历 */ this.preOrderTraverse2 = function (callback) { console.log('非递归先序遍历:'); if (root) { let stack = []; stack.push(root); while (stack.length > 0) { pivot = stack.pop(); console.log('pre: ', pivot.value); if (pivot.right) { stack.push(pivot.right); } if (pivot.left) { stack.push(pivot.left); } } } } /** * 中序遍历binarySearchTree * @param {Function} callback */ this.inOrderTraverse = function (callback) { console.log("中序遍历:"); inOrderTraverseNode(root, callback); } /** * 递归实现中序遍历 * @param {Node} node * @param {Function} callback */ var inOrderTraverseNode = function (node, callback) { if (node != null) { inOrderTraverseNode(node.left, callback); callback(node); inOrderTraverseNode(node.right, callback); } } /** * 非递归中序遍历 * / this.inOrderTraverse2 = function (callback) { console.log('非递归中序遍历:'); if (root) { let stack = []; while (stack.length > 0 || root) { if (root) { stack.push(root); root = root.left; } else { root = stack.pop(); callback(root) root = root.right; } } } } /** * 后序遍历binarySearchTree * @param {Fucntion} callback */ this.postOrderTraverse = function (callback) { console.log("后序遍历:"); postOrderTraverseNode(root, callback); } /** * 递归后续遍历 * @param {Node} node * @param {Function} callback */ var postOrderTraverseNode = function (node, callback) { if (node != null) { postOrderTraverseNode(node.left, callback); postOrderTraverseNode(node.right, callback); callback(node); } } /** * 非递归后序遍历 * / this.postOrderTraverse2 = function (callback) { console.log('非递归后序遍历:'); if (root) { let stack1 = []; let stack2 = []; stack1.push(root); while (stack1.length > 0) { pivot = stack1.pop(); stack2.push(pivot); if (pivot.left) { stack1.push(pivot.left); } if (pivot.right) { stack1.push(pivot.right); } } while (stack2.length > 0) { callback(stack2.pop()) } } } /** * 广度优先遍历 */ this.breadthTraverse = function (callback) { console.log('广度优先遍历:'); breadthTraverseNode(root, callback); } var breadthTraverseNode = function (node, callback) { let stack = []; if (node) { stack.push(node); } while(stack.length > 0) { let cur = stack.shift(); callback(cur); if (cur.left) stack.push(cur.left); if (cur.right) stack.push(cur.right); } } /** * 搜索结点 */ var isFind = false; this.search = function (value) { isFind = false; console.log(`搜索结点${value}`); searchNode(root, value); return isFind; }; /** * 递归搜索结点 * @param {Node} node * @param {Node.value} value */ var searchNode = function (node, value) { if (node != null) { if (isFind) return; if (node.value > value) { searchNode(node.left, value); } else if (node.value < value) { searchNode(node.right, value); } else { isFind = true; } } else { isFind = false; } }; /** * 搜索binarySearchTree中的最小值 */ this.min = () => { console.log("搜索最小值"); return minNode(root); } var minNode = (node) => { if (node) { while (node && node.left != null) { node = node.left; } return node.value; } return null; } /** * 搜索binarySearchTree中最大值 */ this.max = function () { console.log("搜索最大值"); return maxNode(root); } var maxNode = (node) => { if (node != null) { while (node && node.right) { node = node.right; } return node.value; } return null; } /** * 查询树的深度 */ this.depth = function () { return maxDepth(root); } var maxDepth = function (node) { if (!node) return 0; return max(maxDepth(node.left), maxDepth(node.right)) + 1; } } /** * 打印结点值 * @param {Node} node */ var printNode = function (node) { console.log(node.value); } var tree = new BinarySearchTree(); tree.insert(7) tree.insert(4) tree.insert(1) tree.insert(3) tree.insert(11) tree.insert(6) tree.insert(8) tree.insert(9) tree.insert(13) tree.preOrderTraverse(printNode); tree.inOrderTraverse(printNode); tree.postOrderTraverse(printNode); tree.breadthTraverse(printNode); console.log(tree.min()); console.log(tree.max()); console.log("================"); console.log(tree.search(11)); tree.remove(11); tree.preOrderTraverse(printNode); tree.inOrderTraverse(printNode); tree.postOrderTraverse(printNode); console.log(tree.min()); console.log(tree.max()); console.log("================"); console.log(tree.search(11));结果:
先序遍历: 7 4 1 3 6 11 8 9 13 中序遍历: 1 3 4 6 7 8 9 11 13 后序遍历: 3 1 6 4 9 8 13 11 7 广度优先遍历: 7 4 11 1 6 8 13 3 9 搜索最小值 1 搜索最大值 13 ================ 搜索节点11 true 4 1 3 6 13 8 9 中序遍历: 1 3 4 6 7 8 9 13 后序遍历: 3 1 6 4 9 8 13 7 搜索最小值 1 搜索最大值 13 ================ 搜索节点11 false