大话数据结构第一版第二次印刷中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 }
运行结果: