zoukankan      html  css  js  c++  java
  • 数据结构图(带权图)(js)

    一.最小生成树

    永远遵循取最小权值的原则
    如一个顶点到多个顶点,取最小权值
    1.添加边结构

    var Edge = function (sv, dv, d) {
        //起始点
        this.srcVert = sv;
        //重点
        this.destVert = dv;
        //权值
        this.distance = d;
    }

    2.添加优先级队列

    var PriorityQ = function () {
        this.queArray = [];
        this.Max_Size = 10;
        this.length = 0;
    };
    
    PriorityQ.prototype.Insert = function (item) {
        var i;
        //compute distance index
        for (i = 0; i < this.length; i++) {
            if (item.distance >= this.queArray[i].distance)
                break;
        }
        //move
        for (var j = this.length - 1; j >= i; j--) {
            this.queArray[j + 1] = this.queArray[j];
        }
        this.queArray[i] = item;
        this.length++;
    };
    
    PriorityQ.prototype.remove = function () {
        if (arguments.length == 0)
            return this.queArray[--this.length];
        if (arguments.length == 1) {
            for (var j = arguments[0]; j < this.length - 1; j++) {
                this.queArray[j] = this.queArray[j + 1];
            }
            this.length--;
        }
    };
    
    PriorityQ.prototype.peek = function () {
        if (arguments.length == 0)
            return this.queArray[this.length - 1];
        if (arguments.length == 1) {
            return this.queArray[arguments[0]];
        }
    };
    
    PriorityQ.prototype.IsEmpty = function () {
        return this.length == 0;
    }
    
    PriorityQ.prototype.find = function (dex) {
        for (var j = 0; j < this.length; j++) {
            if (this.queArray[j].destVert == dex)
                return j;
        }
        return -1;
    }
    3.1 标记当前项
    this.getCurrentVertex().isInTree = true;
    nTree++;

    3.2将符合条件的权值放入队列中
    for (var j = 0; j < this.length; j++) {
        //skip 
        //if it's us 
        //in the tree
        //no edge
        if (j == this.currentVertIndex)
            continue;
        if (this.vertexList[j].isInTree)
            continue;
        var distance = this.adjMat[this.currentVertIndex][j];
        if (distance == 0)
            continue;
        //put in pq
        //ensure index and distance
        this.putInPQ(j, distance);
    }
    如遇到起点相同的,则比较distance,放弃distance长的那个.
    Graph.prototype.putInPQ=function(newVert, newDist)
    {
        var queueIndex = this.thePQ.find(newVert);
        if (queueIndex != -1) {
            var tempEdge = this.thePQ.peek(queueIndex);
            var oldDist = tempEdge.distance;
            //compare distance
            if (oldDist > newDist) {
                this.thePQ.remove(queueIndex);
                var theEdge = new Edge(this.currentVertIndex, newVert, newDist);
                this.thePQ.Insert(theEdge);
            }
        }
        else {
            //insert directly                    
            var theEdge = new Edge(this.currentVertIndex, newVert, newDist);
            this.thePQ.Insert(theEdge);
        }
    }

    3.4.取最小权值
    if (this.thePQ.length == 0) return;
    //remove minium distance from dq
    var theEdge = this.thePQ.remove();
    var srcVert = theEdge.srcVert;
    this.currentVertIndex = theEdge.destVert;
    //display
    
    this.vertexList[srcVert].Display();
    this.vertexList[this.currentVertIndex].Display();
    完整示例
    Graph.prototype.getCurrentVertex=function()
                {
                   return this.vertexList[this.currentVertIndex];
                }
    
                Graph.prototype.mstw = function () {
                    var nTree = 0;
                    while (nTree < this.length - 1) {
                        //put CurrentVertex in tree
                        this.getCurrentVertex().isInTree = true;
                        nTree++;
    
                        for (var j = 0; j < this.length; j++) {
                            //skip 
                            //if it's us 
                            //in the tree
                            //no edge
                            if (j == this.currentVertIndex)
                                continue;
                            if (this.vertexList[j].isInTree)
                                continue;
                            var distance = this.adjMat[this.currentVertIndex][j];
                            if (distance == 0)
                                continue;
                            //put in pq
                            //ensure index and distance
                            this.putInPQ(j, distance);
                        }
                        if (this.thePQ.length == 0) return;
                        //remove minium distance from dq
                        var theEdge = this.thePQ.remove();
                        var srcVert = theEdge.srcVert;
                        this.currentVertIndex = theEdge.destVert;
                        //display
    
                        this.vertexList[srcVert].Display();
                        this.vertexList[this.currentVertIndex].Display();
                    }
                }
              Graph.prototype.putInPQ=function(newVert, newDist)
              {
                  var queueIndex = this.thePQ.find(newVert);
                  if (queueIndex != -1) {
                      var tempEdge = this.thePQ.peek(queueIndex);
                      var oldDist = tempEdge.distance;
                      //compare distance
                      if (oldDist > newDist) {
                          this.thePQ.remove(queueIndex);
                          var theEdge = new Edge(this.currentVertIndex, newVert, newDist);
                          this.thePQ.Insert(theEdge);
                      }
                  }
                  else {
                      //insert directly                    
                      var theEdge = new Edge(this.currentVertIndex, newVert, newDist);
                      this.thePQ.Insert(theEdge);
                  }
              }


    二.求最短路径

    迪杰斯特拉(Dijkstra)算法求顶点0到其他各顶点的最短路径


    1.用于保存之前顶点到当前顶点的距离

        class DistPar             // distance and parent
        {                      // items stored in sPath array
            public int distance;   // distance from start to this vertex
            public int parentVert; // current parent of this vertex
            // -------------------------------------------------------------
            public DistPar(int pv, int d)  // constructor
            {
                distance = d;
                parentVert = pv;
            }
            // -------------------------------------------------------------
        }  // end class DistPar
    

    2.将第一个顶点标记为在树中

          int startTree = 0;             // start at vertex 0
          vertexList[startTree].isInTree = true;
          nTree = 1;                     // put it in tree

    3.初始化读取顶点到各个顶点的距离,如果没有边则距离为无穷大

    // transfer row of distances from adjMat to sPath
    for(int j=0; j<nVerts; j++)
       {
       int tempDist = adjMat[startTree][j];
       sPath[j] = new DistPar(startTree, tempDist);
       }

    4.进入回圈

    4.1在各点中取距离最小的点

    int indexMin = getMin();    // get minimum from sPath
    int minDist = sPath[indexMin].distance;


    4.2记录距离最小的点的索引值和距离,并把该顶点标记入树

    if(minDist == INFINITY)     // if all infinite
              {                        // or in tree,
              System.out.println("There are unreachable vertices");
              break;                   // sPath is complete
              }
           else
              {                        // reset currentVert
              currentVert = indexMin;  // to closest vert
              startToCurrent = sPath[indexMin].distance;
              // minimum distance from startTree is
              // to currentVert, and is startToCurrent
              }
           // put current vertex in tree
           vertexList[currentVert].isInTree = true;
    4.3 当把当前索引顶点记录之后,然后获取该顶点到各顶点的距离
                int column = 1;                // skip starting vertex
    while(column < nVerts)         // go across columns
       {
    
       int currentToFringe = adjMat[currentVert][column];
    }
    4.4记录上个距离和当前距离的和
    int startToFringe = startToCurrent + currentToFringe;
    4.5与第一个顶点到该节点的距离和startToFringe 进行比较,然后取短路径.并更新sPath的顶点和距离.
    比如A到B是60,B到C是50,A到C是150,那么A经过B再到C的路径小于A直接到C的距离,则产生了最小路径
             int sPathDist = sPath[column].distance;
    
    // compare distance from start with sPath entry
    if(startToFringe < sPathDist)   // if shorter,
       {                            // update sPath
       sPath[column].parentVert = currentVert;
       sPath[column].distance = startToFringe;
       }
    完整(核心
    public void adjust_sPath()
          {
          // adjust values in shortest-path array sPath
          int column = 1;                // skip starting vertex
          while(column < nVerts)         // go across columns
             {
             // if this column's vertex already in tree, skip it
             if( vertexList[column].isInTree )
                {
                column++;
                continue;
                }
             // calculate distance for one sPath entry
                           // get edge from currentVert to column
             int currentToFringe = adjMat[currentVert][column];
                           // add distance from start
             int startToFringe = startToCurrent + currentToFringe;
                           // get distance of current sPath entry
             int sPathDist = sPath[column].distance;
    
             // compare distance from start with sPath entry
             if(startToFringe < sPathDist)   // if shorter,
                {                            // update sPath
                sPath[column].parentVert = currentVert;
                sPath[column].distance = startToFringe;
                }
             column++;
             }  // end while(column < nVerts)
        }
    等sPath更新完毕后就是最小路径了

    输出

    Shortest paths
    CurrentVert  1  distance  50
    before begin sPath----------------
    ParentVert/SelfVert  0  0   InTree  true   distance  1000000
    ParentVert/SelfVert  0  1   InTree  true   distance  50
    ParentVert/SelfVert  0  2   InTree  false   distance  1000000
    ParentVert/SelfVert  0  3   InTree  false   distance  80
    ParentVert/SelfVert  0  4   InTree  false   distance  1000000
    before end sPath----------------
    Start/Vert/column  0  1  2  distance  60  total undirect  110  sPathDist direct  1000000
    2  changed
    Start/Vert/column  0  1  3  distance  90  total undirect  140  sPathDist direct  80
    Start/Vert/column  0  1  4  distance  1000000  total undirect  1000050  sPathDist direct  1000000
    adjusted begin sPath----------------
    ParentVert/SelfVert  0  0   InTree  true   distance  1000000
    ParentVert/SelfVert  0  1   InTree  true   distance  50
    ParentVert/SelfVert  1  2   InTree  false   distance  110
    ParentVert/SelfVert  0  3   InTree  false   distance  80
    ParentVert/SelfVert  0  4   InTree  false   distance  1000000
    adjusted end sPath----------------
    CurrentVert  3  distance  80
    before begin sPath----------------
    ParentVert/SelfVert  0  0   InTree  true   distance  1000000
    ParentVert/SelfVert  0  1   InTree  true   distance  50
    ParentVert/SelfVert  1  2   InTree  false   distance  110
    ParentVert/SelfVert  0  3   InTree  true   distance  80
    ParentVert/SelfVert  0  4   InTree  false   distance  1000000
    before end sPath----------------
    Start/Vert/column  0  3  2  distance  20  total undirect  100  sPathDist direct  110
    2  changed
    Start/Vert/column  0  3  4  distance  70  total undirect  150  sPathDist direct  1000000
    4  changed
    adjusted begin sPath----------------
    ParentVert/SelfVert  0  0   InTree  true   distance  1000000
    ParentVert/SelfVert  0  1   InTree  true   distance  50
    ParentVert/SelfVert  3  2   InTree  false   distance  100
    ParentVert/SelfVert  0  3   InTree  true   distance  80
    ParentVert/SelfVert  3  4   InTree  false   distance  150
    adjusted end sPath----------------
    CurrentVert  2  distance  100
    before begin sPath----------------
    ParentVert/SelfVert  0  0   InTree  true   distance  1000000
    ParentVert/SelfVert  0  1   InTree  true   distance  50
    ParentVert/SelfVert  3  2   InTree  true   distance  100
    ParentVert/SelfVert  0  3   InTree  true   distance  80
    ParentVert/SelfVert  3  4   InTree  false   distance  150
    before end sPath----------------
    Start/Vert/column  0  2  4  distance  40  total undirect  140  sPathDist direct  150
    4  changed
    adjusted begin sPath----------------
    ParentVert/SelfVert  0  0   InTree  true   distance  1000000
    ParentVert/SelfVert  0  1   InTree  true   distance  50
    ParentVert/SelfVert  3  2   InTree  true   distance  100
    ParentVert/SelfVert  0  3   InTree  true   distance  80
    ParentVert/SelfVert  2  4   InTree  false   distance  140
    adjusted end sPath----------------
    CurrentVert  4  distance  140
    before begin sPath----------------
    ParentVert/SelfVert  0  0   InTree  true   distance  1000000
    ParentVert/SelfVert  0  1   InTree  true   distance  50
    ParentVert/SelfVert  3  2   InTree  true   distance  100
    ParentVert/SelfVert  0  3   InTree  true   distance  80
    ParentVert/SelfVert  2  4   InTree  true   distance  140
    before end sPath----------------
    adjusted begin sPath----------------
    ParentVert/SelfVert  0  0   InTree  true   distance  1000000
    ParentVert/SelfVert  0  1   InTree  true   distance  50
    ParentVert/SelfVert  3  2   InTree  true   distance  100
    ParentVert/SelfVert  0  3   InTree  true   distance  80
    ParentVert/SelfVert  2  4   InTree  true   distance  140
    adjusted end sPath----------------
    A=inf(A) B=50(A) C=100(D) D=80(A) E=140(C)

    步骤总结:
    1.选定一个顶点为根记做A
    2.选择该顶点的最小边记做B,并记录这条边与A相交的顶点C,并标记入树C
    3.计算C点到各顶点(不在树中的)的边的长度并与(A到各顶点的边)相比较,选择路径小者对A进行更新,并记录该顶点(以便排序顶点输出)
    4.重复2-3步骤,等所有顶点都在树中时,则A到各顶点的最小路径更新完毕

    这属于一个贪婪算法,总是先选最小的权值
    终于搞懂了微笑 理解后,其实也不难.多看看中间步骤,一步到位很难理解

    三.弗洛伊德(Floyed)算法求每一对顶点之间的最短路径的

  • 相关阅读:
    UCML破解
    UCML快速开发平台学习1-UCML环境安装
    window系统安装jdk,jre
    解决Android报错No resource found that matches the given name (at 'text' with value '@string/hello').
    es6小技巧整理
    如何将项目推到github上面
    如何将时间格式化
    uni-app 页面跳转的两种方法
    layui表单校验及监听复选框选中状态的坑
    使用nvm管理多个不同版本的nodeJS之安装成功nodeJs之后使用npm报错的问题
  • 原文地址:https://www.cnblogs.com/Clingingboy/p/1800265.html
Copyright © 2011-2022 走看看