前面介绍过一种非顺序数据结构是散列表,本文将详细介绍另一种非顺序数据结构——树,它对于存储需要快速查找的数据非常有用
二叉树、满二叉树、完全二叉树、堆、二叉搜索树BST/二叉查找树/二叉排序树
二叉搜索树是我们这章要研究的数据结构
1.树-创建BinarySearchTree类
function BinarySearchTree() { var Node = function(key){ //{1} 节点包括键、左侧子节点、右侧子节点 this.key = key; //键 this.left = null; //左侧子节点 this.right = null; //右侧子节点 }; var root = null; //{2} //根元素 }然后,我们需要实现一些方法。下面是将要在树类中实现的方法: insert(key):向树中插入一个新的键。 search(key):在树中查找一个键,如果节点存在,则返回true;如果不存在,则返回 false。 inOrderTraverse:通过中序遍历方式遍历所有节点。 preOrderTraverse:通过先序遍历方式遍历所有节点。 postOrderTraverse:通过后序遍历方式遍历所有节点。 min:返回树中最小的值/键。 max:返回树中最大的值/键。 remove(key):从树中移除某个键。
2.insert
//插入insert this.insert = function(key){ var newNode = new Node(key); if(root === null){ root = newNode; }else{ insertNode(root,newNode); } } var insertNode = function(node,newNode){ if(newNode.key < node.key){ 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); } } }3.树的遍历
//var tree = new BinarySearchTree(); //中序遍历 this.inOrderTraverse = function(callback){ inOrderTraverseNode(root,callback); } var inOrderTraverseNode = function(node,callback){ if (node!==null) { inOrderTraverseNode(node.left,callback); callback(node.key); inOrderTraverseNode(node.right,callback); } } //回调函数callback function printNode(value){ console.log(value); } //tree调用中序遍历 tree.inOrderTraverse(printNode);4.树的搜索
//树的搜索(最小值、最大值、特定值) this.min = function(){ return minNode(root); } var minNode = function(node){ if(node){ while(node && node.left !== null){ node = node.left; } return node.key; } return null; } this.search = function(key){ return searchNode(root,key); } var 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; } }5.树的移除
//移除一个节点 this.remove = function(key){ root = removeNode(root,key); } var 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{ //键等于node.key //第一种情况——一个叶节点 if (node.left === null && node.right === null){ //{9} node = null; //{10} return node; //{11} } //第二种情况——一个只有一个子节点的节点 if (node.left === null){ //{12} node = node.right; //{13} return node; //{14} } else if (node.right === null){ //{15} node = node.left; //{16} return node; //{17} } //第三种情况——一个有两个子节点的节点 var aux = findMinNode(node.right); //{18} node.key = aux.key; //{19} node.right = removeNode(node.right, aux.key); //{20} return node; //{21} } }更多可以参考:https://www.cnblogs.com/xiaohuochai/p/8184989.html#anchor4
附注一张图: 在这里插入图片描述