讀古今文學網 > 學習JavaScript數據結構與算法(第2版) > 9.3 創建Graph類 >

9.3 創建Graph類

照例,我們聲明類的骨架:

function Graph {
  var vertices = ; //{1}
  var adjList = new Dictionary; //{2}
}

  

我們使用一個數組來存儲圖中所有頂點的名字(行{1}),以及一個字典(在第7章中已經實現)來存儲鄰接表(行{2})。字典將會使用頂點的名字作為鍵,鄰接頂點列表作為值。vertices數組和adjList字典兩者都是我們Graph類的私有屬性。

接著,我們將實現兩個方法:一個用來向圖中添加一個新的頂點(因為圖實例化後是空的),另外一個方法用來添加頂點之間的邊。我們先實現addVertex方法:

this.addVertex = function(v){
  vertices.push(v); //{3}
  adjList.set(v, ); //{4}
};

  

這個方法接受頂點v作為參數。我們將該頂點添加到頂點列表中(行{3}),並且在鄰接表中,設置頂點v作為鍵對應的字典值為一個空數組(行{4})。

現在,我們來實現addEdge方法:

this.addEdge = function(v, w){
  adjList.get(v).push(w); //{5}
  adjList.get(w).push(v); //{6}
};

  

這個方法接受兩個頂點作為參數。首先,通過將w加入到v的鄰接表中,我們添加了一條自頂點v到頂點w的邊。如果你想實現一個有向圖,則行{5}就足夠了。由於本章中大多數的例子都是基於無向圖的,我們需要添加一條自wv的邊(行{6})。

 請注意我們只是往數組裡新增元素,因為數組已經在行{4}被初始化了。

讓我們測試這段代碼:

var graph = new Graph;
var myVertices = ['A','B','C','D','E','F','G','H','I']; //{7}
for (var i=0; i<myVertices.length; i++){ //{8}
  graph.addVertex(myVertices[i]);
}
graph.addEdge('A', 'B'); //{9}
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');

  

為方便起見,我們創建了一個數組,包含所有我們想添加到圖中的頂點(行{7})。接下來,我們只要遍歷vertices數組並將其中的值逐一添加到我們的圖中(行{8})。最後,我們添加想要的邊(行{9})。這段代碼將會創建一個圖,也就是到目前為止本章的示意圖所使用的。

為了更方便一些,讓我們來實現一下Graph類的toString方法,以便於在控制台輸出圖。

this.toString = function{
  var s = '';
  for (var i=0; i<vertices.length; i++){ //{10}
    s += vertices[i] + ' -> ';
    var neighbors = adjList.get(vertices[i]); //{11}
    for (var j=0; j<neighbors.length; j++){ //{12}
      s += neighbors[j] + ' ';
    }
    s += '\n'; //{13}
  }
  return s;
};

  

我們為鄰接表表示法構建了一個字符串。首先,迭代vertices數組列表(行{10}),將頂點的名字加入字符串中。接著,取得該頂點的鄰接表(行{11}),同樣也迭代該鄰接表(行{12}),將相鄰頂點加入我們的字符串。鄰接表迭代完成後,給我們的字符串添加一個換行符(行{13}),這樣就可以在控制台看到一個漂亮的輸出了。運行如下代碼:

console.log(graph.toString);

  

輸出如下:

A -> B C D
B -> A E F
C -> A D G
D -> A C G H
E -> B I
F -> B
G -> C D
H -> D
I -> E

  

一個漂亮的鄰接表!從該輸出中,我們知道頂點A有這幾個相鄰頂點:BCD