Javascript二叉搜索树实现

来源:互联网 发布:linux 批量删除文件名 编辑:程序博客网 时间:2024/05/29 19:35

基本知识

二叉树:二叉树的所有结点的最大度数为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);       return node;     } else if (value > node.value) {       node.right = removeNode(node.right, value);       return node;     } else {       //该结点为叶子结点       if (node.left === null && node.rigth === null) {         node = null;         return node;       }       //该结点有一个子结点       else if (node.left === null) {         node = node.right;        //  node.right = null;         return node;       } else if (node.right === null) {         node = node.left;        //  node.left = null;         return node;       }       //该结点有两个子结点,此时可以取左子树中的最大值代替根结点;当然也可以取右子树中的最小值代替根结点       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);     }   }   /**    * 中序遍历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);     }   }   /**    * 后序遍历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);     }   }   /**    * 搜索结点    */   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;  }}/*** 打印结点值* @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);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));

结果:

8913中序遍历:13467891113后序遍历:31649813117搜索最小值1搜索最大值13================搜索节点11true41361389中序遍历:134678913后序遍历:316498137搜索最小值1搜索最大值13================搜索节点11false
原创粉丝点击