大話數據結構第一版第二次印刷中P231-P232中的無向圖的鄰接表創建,解釋有一點小問題,但是不影響無向圖鄰接表的創建。
書中無向圖如下:
問題如下:
1、如果data信息是V0,V1,V2,V3,需要typedef char VertexType[3];我為了方便,將V0,V1,V2,V3分別改為ABCD。
2、根據圖7-4-6,V0的firstedge指向V1,V1的firstedge指向V0,V2的firstedge指向V0,V3的firstedge指向V1。但是這個代碼,最終創建結果是,V0的firstedge指向V3,V1的firstedge指向V2,V2的firstedge指向V3,V3的firstedge指向V2。正好與圖的畫法顛倒了,但是代碼同樣能創建出一個無向圖。
注意:對於鄰接表結構,一定要注意的是邊表節點,是為了尋找設計的結構,不是頂點。通過頂點的firstedge找到與它相連的第一個頂點,再通過與該頂點相連的第一個頂點找到與該頂點相連的第二個頂點,於此類推。類似於二叉樹中的孩子節點表示法。
上面的結構應該改為如下結構:
代碼和解釋如下(VS2012測試通過):
1 #include <iostream> 2 #include <stdlib.h> 3 using namespace std; 4 5 typedef struct EdgeNode//邊表節點 6 { 7 int adjvex;//存儲該頂點對應的下標 8 struct EdgeNode *next;//指向該頂點的下一個鄰接點 9 }EdgeNode; 10 11 typedef struct VertexNode//頂點表結點 12 { 13 char data;//頂點 14 EdgeNode *firstedge;//邊表頭指針 15 }VertexNode; 16 17 typedef struct//圖的鄰接表存儲結構 18 { 19 VertexNode adjList[4];//有4個VertexNode這種類型的頂點,定義一個數組adjList[4],每個元素是VertexNode類型 20 int numVertexes,numEdges;//圖中頂點數和邊數,這里是4,5 21 }GraphAdjList; 22 23 GraphAdjList *CreateALGraph(GraphAdjList *Gp)//無向圖的鄰接表創建 24 { 25 Gp=(GraphAdjList *)malloc(sizeof(GraphAdjList)); 26 //申請一片GraphAdjList大小的類型很重要,否則Gp指向NULL(GL傳的值是NULL),程序就運行崩潰了 27 EdgeNode *pe;//定義邊表指針類型pe 28 cout << "input numNodes and numEdges:" << endl; 29 cin >> Gp->numVertexes >> Gp->numEdges;//輸入4 5 30 for (int k = 0 ; k < Gp->numVertexes; k++) 31 { 32 cout << "input VertexType data:" << endl; 33 cin >> Gp->adjList[k].data;//輸入A B C D 34 Gp->adjList[k].firstedge = NULL;//將邊表頭指針指向NULL,即置為0 35 } 36 for (int k = 0; k < Gp->numEdges; k++)//建立邊表 37 { 38 int i,j; 39 cout << "input vi and vj:" << endl; 40 cin >> i >> j;//每次循環依次輸入0 1,0 2,0 3,1 2,2 3 41 42 pe = (EdgeNode *)malloc(sizeof(EdgeNode)); 43 pe->adjvex = j;// 鄰接序號為j 44 pe->next = Gp->adjList[i].firstedge;//將pe的指針指向當前頂點指向的結點 45 Gp->adjList[i].firstedge = pe;//將當前頂點的指針指向pe 46 47 pe = (EdgeNode *)malloc(sizeof(EdgeNode)); 48 pe->adjvex = i; 49 pe->next = Gp->adjList[j].firstedge; 50 Gp->adjList[j].firstedge = pe;//無序圖重復上面步驟 51 } 52 return Gp; 53 } 54 55 int main(void) 56 { 57 GraphAdjList *GL=NULL; 58 GL=CreateALGraph(GL); 59 //以下是驗證圖的創建是否正確 60 cout<<GL->adjList[0].firstedge->adjvex<<endl;//輸出3,A的第一個指向是D 61 cout<<GL->adjList[0].firstedge->next->adjvex<<endl;//輸出2,A第二個指向是C 62 cout<<GL->adjList[0].firstedge->next->next->adjvex<<endl;//輸出1,A的第三個指向是B 63 cout<<GL->adjList[1].firstedge->adjvex<<endl;//輸出2,B的第一個指向是C 64 cout<<GL->adjList[1].firstedge->next->adjvex<<endl;//輸出0,B第二個指向是A 65 cout<<GL->adjList[2].firstedge->adjvex<<endl;//輸出3,C的第一個指向是D 66 cout<<GL->adjList[2].firstedge->next->adjvex<<endl;//輸出1,C第二個指向是B 67 cout<<GL->adjList[2].firstedge->next->next->adjvex<<endl;//輸出0,C的第三個指向是A 68 cout<<GL->adjList[3].firstedge->adjvex<<endl;//輸出2,D的第一個指向是C 69 cout<<GL->adjList[3].firstedge->next->adjvex<<endl;//輸出0,D第二個指向是A 70 return 0; 71 }
運行結果: