zoukankan      html  css  js  c++  java
  • 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&&current.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 += '
    '
            }
            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
          }
        }
    

      

       

  • 相关阅读:
    xib上的控件属性为什么要使用weak
    authenticating with the app store 一直卡住--问题记录
    ios-tableview加载卡顿的解决方案
    魔链的参考文档--移动应用之deeplink唤醒app
    iOS中Category和Extension 原理详解
    剑指offer 9-10:青蛙跳台阶与Fibonacii数列
    剑指offer 8:旋转数组的最小数字
    设计模式:单例模式(singleton)
    设计模式:工厂模式
    C++智能指针解析
  • 原文地址:https://www.cnblogs.com/sunliyuan/p/13934304.html
Copyright © 2011-2022 走看看