日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

数据结构图(带权图)(js)

發布時間:2023/12/15 综合教程 28 生活家
生活随笔 收集整理的這篇文章主要介紹了 数据结构图(带权图)(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)算法求每一對頂點之間的最短路徑的

總結

以上是生活随笔為你收集整理的数据结构图(带权图)(js)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。