js二叉搜索树和图

//封装二分搜索树
function BinarySerachTree(){
function Node(key){
this.key=key
this.left=null
this.right=null
}
//属性
this.root=null
//方法
//插入数据
BinarySerachTree.prototype.insert=function(key){
//1.判断 key创建节点
var newNode=new Node(key)
//2.判断接节点是否有值
if(this.root==null){
this.root=newNode
}else{
this.insertNode(this.root,newNode)
}
}
BinarySerachTree.prototype.insertNode=function(node,newNode){
if(newNode.key<node.key){ //向左查找
if(node.left==null){
node.left=newNode
}else{
this.insertNode(node.left,newNode)
}
}else{ //向右查找
if(node.right==null){
node.right=newNode
}else{
this.insertNode(node.right,newNode)
}
}
}
//树的遍历
//1.先序遍历
BinarySerachTree.prototype.preOrderTraversal=function(handler){
this.preOrderTraversalNode(this.root,handler)
}
BinarySerachTree.prototype.preOrderTraversalNode=function(node,handler){
if(node!=null){
//1.处理经过的节点
handler(node.key)
//2.处理经过节点的左子节点
this.preOrderTraversalNode(node.left,handler)
//3.处理经过的右子节点
this.preOrderTraversalNode(node.right,handler)
}
}
//2.中序遍历
BinarySerachTree.prototype.midOrderTraversal=function(handler){
this.midOrderTraversalNode(this.root,handler)
}
BinarySerachTree.prototype.midOrderTraversalNode=function(node,handler){
if(node!=null){
//1.处理左子树中的节点
this.midOrderTraversalNode(node.left,handler)
//2.处理节点
handler(node.key)
//3.处理右字数中的节点
this.midOrderTraversalNode(node.right,handler)
}
}
//3.后序遍历
BinarySerachTree.prototype.postOrderTraversal=function(handler){
this.postOrderTraversalNode(this.root,handler)
}
BinarySerachTree.prototype.postOrderTraversalNode=function(node,handler){
if(node!==null){
//1.查找左子树中的节点
this.postOrderTraversalNode(node.left,handler)
//2.查找右子树中的节点
this.postOrderTraversalNode(node.right,handler)
//3.处理节点
handler(node.key)
}
}
//寻找最大值
BinarySerachTree.prototype.max=function(){
//1.获取根节点
var node=this.root
//2.依次向右不断的查找,直到节点为 null
var key=null
while(node!=null){
key=node.key
node=node.right
}
return key
}
//2.寻找最小值
BinarySerachTree.prototype.min=function(){
//1.获取根节点
var node=this.root
//2.依次向左不断的查找,直到节点为 null
var key=null
while(node!=null){
key=node.key
node=node.left
}
return key
}
//3.搜索特定的值
BinarySerachTree.prototype.search=function(key){
return this.searchNode(this.root,key)
}
//递归实现
BinarySerachTree.prototype.searchNode=function(node,key){
//1.如果传入的 node 为 null ,就推出递归
if(node==null) return false
//2.判断 node 节点的值和传入的key 大小
if(node.key>key){ //传入的 key 较小,向左继续查找
return this.searchNode(node.left,key)
}else if(node.key<key){ //传入的 key较大,向右边继续查找
return this.searchNode(node.right,key)
}else{ //2.3相同,说明找到了 key
return true
}
}
//循环实现
BinarySerachTree.prototype.search1=function(key){
//1.获取根节点
var node=this.root
//2.循环来搜索 key
while(node!=null){
if(key<node.key){
node=node.left
}else if(key>node.key){
node=node.right
}else{
return true
}
}
return false
}
//删除节点
BinarySerachTree.prototype.remove=function(key){
//1.寻找要删除的节点
//1.1定义变量,保存一些信息
var current=this.root
var parent=null
var isLeftChild=true
//1.2开始寻找删除的节点
while(current.key!=key){
parent=current
if(key<current.key){
isLeftChild=true
current=current.left
}else {
isLeftChild=false
current=current.right
}
//某种情况,已经找到了最后的节点,依然没有找到==key
if(current==null) return false
}
//2.根据对应的情况删除节点
//2.1删除的节点是叶子节点(没有子节点)
if(current.left==null&¤t.right==null){
if(current==this.root) this.root=null
else if(isLeftChild){
parent.left=null
}else{
parent.right=null
}
}
//2.2删除的节点有一个叶子节点
else if(current.right==null){
if(current==this.root){
this.root=current.left
}else if(isLeftChild){
parent.left=current.left
}else{
parent.right=current.left
}
}else if(current.left==null){
if(current==this.root){
this.root==current.right
}else if(isLeftChild){
parent.left=current.right
}else{
parent.right=current.right
}
}
//2.3删除的节点有两个节点
else{
//1.获取后继节点
var successor=this.getSuccessor(current)
//2.判断是否根节点
if(current==this.root) this.root=successor
else if(isLeftChild) parent.left=successor
else parent.right=successor
//3.将删除节点的左子树= current.left
successor.left=current.left
}
}
//找后继的方法
BinarySerachTree.prototype.getSuccessor=function(delNode){
//1.定义变量,保存找到的后继
var successor=delNode
var current=delNode.right
var successorParent=delNode
//2.循环查找
while(current!=null){
successorParent=successor
successor=current
current=current.left
}
//3.判断寻找到的后继节点是否直接就是delNode的 right节点
if(successor!=delNode.right){
successorParent.left=successorParent.right
successor.right=delNode.right
}
return successor
}
}
//测试代码
var bst=new BinarySerachTree()
//2.插入数据
bst.insert(11)
bst.insert(7)
bst.insert(15)
bst.insert(5)
bst.insert(3)
bst.insert(9)
bst.insert(8)
bst.insert(10)
bst.insert(13)
bst.insert(12)
bst.insert(20)
bst.insert(18)
bst.insert(25)
bst.insert(6)
//3.测试线序遍历
// var resultString=''
// bst.preOrderTraversal(function(key){
// resultString+=key+" "
// })
//alert(resultString)
//2.测试中序遍历
// resultString=""
// bst.midOrderTraversal(function(key){
// resultString+=key +" "
// })
// alert(resultString)
//3.测试后序遍历
resultString=""
bst.postOrderTraversal(function(key){
resultString+=key +" "
})
// alert(resultString)
// alert(bst.max())
// alert(bst.min())
//5.测试搜索方法
// alert(bst.search(25))
// alert(bst.search(24))
// alert(bst.search(2))
// alert(bst.search1(25))
// alert(bst.search1(24))
// alert(bst.search1(2))
bst.remove(9)
bst.remove(7)
bst.remove(15)
resultString=""
bst.postOrderTraversal(function(key){
resultString+=key+" "
})
alert(resultString)
红黑树的特点:

图的特点:

图:
//封装图结构
function Graph(){
//属性 顶点(数组) /边(字典)
this.vertexes=[] //顶点
this.edges=new Dictionary() //边
//方法
//1.添加顶点的方法
Graph.prototype.addVertex=function(v){
this.vertexes.push(v)
this.edges.set(v,[])
}
//2.添加边的方法
Graph.prototype.addEdge=function(v1,v2){
this.edges.get(v1).push(v2)
this.edges.get(v1).push(v1)
}
//三.实现toString方法:转换为邻接表形式
Graph.prototype.toString = function (){
//1.定义字符串,保存最终结果
let resultString = ""
//2.遍历所有的顶点以及顶点对应的边
for (let i = 0; i < this.vertexes.length; i++) {//遍历所有顶点
resultString += this.vertexes[i] + '-->'
let vEdges = this.edges.get(this.vertexes[i])
for (let j = 0; j < vEdges.length; j++) {//遍历字典中每个顶点对应的数组
resultString += vEdges[j] + ' ';
}
resultString += '\n'
}
return resultString
}
//初始化状态颜色
Graph.prototype.initializeColor=function(){
var colors=[]
for(var i=0;i<this.vertexes.length;i++){
colors[this.vertexes[i]]='white'
}
return colors
}
//实现广度优先搜索
Graph.prototype.bfs=function(initV,handler){
//1.初始化颜色
var colors=this.initializeColor()
//2.创建队列
var queue=new Queue()
//3.将顶点加入到队列中
queue.enqueue(initV)
//4.循环从队列中取出元素
while(!queue.isEmpty()){
//4.1从队列中取出一个顶点
var v=queue.dequeue()
//4.2获取和顶点相连的另外顶点
var vList=this.edges.get(v)
//4.3将 v 的颜色设置成灰色
colors[v]='gray'
//4.4遍历所有的顶点,并且加入到队列中
for(var i=0;i<vList.length;i++){
var e=vList[i]
if(colors[e]=='white'){
colors[e]='gray'
queue.enqueue(e)
}
}
//4.5 v已经被探测,并且访问
handler(v)
//4.6 将顶点设置为黑色
colors[v] = 'black'
}
}
//深度优先搜索(DFS)
Graph.prototype.dfs=function(initV,handler){
//1.初始化颜色
var colors=this.initializeColor()
//2.从某个顶点开始依次递归访问
this.dfsVisit(initV,colors,handler)
}
Graph.prototype.dfsVisit=function(v,colors,handler){
//1.将颜色设置为灰色
colors[v]='gray'
//2.处理v 顶点
handler(v)
//3.访问 v 相邻的顶点
var vList=this.edges.get(v)
for(var i=0;i<vList.length;i++){
var e=vList[i]
if(colors[e]=='white'){
this.dfsVisit(e,colors,handler)
}
}
//4.将 v 设置成黑色
colors[v]='black'
}
}
//测试代码
var graph=new Graph()
//2.添加顶点
var myVertexes=['A','B','C','D','E','F','G','H','I']
//g.vertexes=myVertexes
for(var i=0;i<myVertexes.length;i++){
graph.addVertex(myVertexes[i])
}
//3.添加边
graph.addEdge('A', 'B')
graph.addEdge('A', 'C')
graph.addEdge('A', 'D')
graph.addEdge('C', 'D')
graph.addEdge('C', 'G')
graph.addEdge('D', 'G')
graph.addEdge('D', 'H')
graph.addEdge('B', 'E')
graph.addEdge('B', 'F')
graph.addEdge('E', 'I')
//alert(graph)
//console.log(graph.toString());
//5.测试bfs
// var result=''
// graph.bfs(graph.vertexes[0],function(v){
// result+=v + ' '
// })
// alert(result)
//6.测试 dfs
result=''
graph.dfs(graph.vertexes[0],function(v){
result+= v+' '
})
alert(result)
//封装字典类
function Dictionary(){
//字典属性
this.items = {}
//字典操作方法
//一.在字典中添加键值对
Dictionary.prototype.set = function(key, value){
this.items[key] = value
}
//二.判断字典中是否有某个key
Dictionary.prototype.has = function(key){
return this.items.hasOwnProperty(key)
}
//三.从字典中移除元素
Dictionary.prototype.remove = function(key){
//1.判断字典中是否有这个key
if(!this.has(key)) return false
//2.从字典中删除key
delete this.items[key]
return true
}
//四.根据key获取value
Dictionary.prototype.get = function(key){
return this.has(key) ? this.items[key] : undefined
}
//五.获取所有keys
Dictionary.prototype.keys = function(){
return Object.keys(this.items)
}
//六.size方法
Dictionary.prototype.keys = function(){
return this.keys().length
}
//七.clear方法
Dictionary.prototype.clear = function(){
this.items = {}
}
}
// 基于数组封装队列类
function Queue() {
// 属性
this.items = []
// 方法
// 1.将元素加入到队列中
Queue.prototype.enqueue = element => {
this.items.push(element)
}
// 2.从队列中删除前端元素
Queue.prototype.dequeue = () => {
return this.items.shift()
}
// 3.查看前端的元素
Queue.prototype.front = () => {
return this.items[0]
}
// 4.查看队列是否为空
Queue.prototype.isEmpty = () => {
return this.items.length == 0;
}
// 5.查看队列中元素的个数
Queue.prototype.size = () => {
return this.items.length
}
// 6.toString方法
Queue.prototype.toString = () => {
let resultString = ''
for (let i of this.items){
resultString += i + ' '
}
return resultString
}
}

浙公网安备 33010602011771号