6.4.2 毗邻表
接纳毗邻表表现法创建无向图
- //算法6.2 采用邻接表表示法创建无向图
- #include <stdio.h>
- #include <stdlib.h>
- #define MVNum 100
- typedef int OtherInfo; //假设在边结点中的数据域存储边的权值,且边的权值类型为整型
- typedef char VerTexType; //假设顶点的数据类型为字符型
- typedef struct ArcNode
- {
- int adjvex;
- struct ArcNode* nextarc;
- OtherInfo info;
- }ArcNode; //边结点
- typedef struct VNode
- {
- VerTexType data;
- ArcNode* firstarc;
- }VNode,AdjList[MVNum]; //表头结点
- typedef struct
- {
- AdjList vertices; //存储所有顶点
- int vexnum; //顶点总数
- int arcnum; //总边数
- }ALGraph; //图的信息
- void CreateUDG(ALGraph& G);
- int LocateVex(ALGraph& G, VerTexType v);
- void printALGraph(ALGraph &G);
- int main()
- {
- ALGraph G = { {'\0',NULL}, 0,0};
- CreateUDG(G);
- printALGraph(G);
- return 0;
- }
- void CreateUDG(ALGraph& G)
- {
- int i = 0;
- int k = 0;
- VerTexType v1 = 0;
- VerTexType v2 = 0;
- int j = 0;
- ArcNode *p1 = NULL;
- ArcNode *p2 = NULL;
- printf("请输入无向图的总顶点数:");
- scanf_s(" %d", &G.vexnum);
- printf("请输入无向图的总边数:");
- scanf_s(" %d", &G.arcnum);
- for (i = 0; i < G.vexnum; ++i)
- {
- printf("请输入第%d个顶点的值:", i + 1);
- scanf_s(" %c", &(G.vertices[i].data));
- G.vertices[i].firstarc = NULL; //初始化
- }
- for (k = 0; k < G.arcnum; k++)
- {
- printf("请输入第%d条边依附的两个顶点(用空格间隔,输入结束后按回车): ", k + 1);
- scanf_s(" %c %c", &v1, sizeof(VerTexType), &v2, sizeof(VerTexType));
- i = LocateVex(G, v1);
- j = LocateVex(G, v2);
- p1 = (ArcNode*)malloc(sizeof(ArcNode));
- p1->adjvex = j;
- p1->nextarc = G.vertices[i].firstarc;
- G.vertices[i].firstarc = p1; //将新结点*p1插入顶点Vi的边表头部
- p2 = (ArcNode*)malloc(sizeof(ArcNode));
- p2->adjvex = i;
- p2->nextarc = G.vertices[j].firstarc;
- G.vertices[j].firstarc = p2; //将与*p1对称的新的边结点*p2插入顶点Vj的边表头部
- }
- }
- //在G的顶点表vexs中获取字符v的下标(数组G.vexs的下标从0开始)
- int LocateVex(ALGraph& G, VerTexType v)
- {
- int i = 0;
- for (i = 0; i < G.vexnum && (G.vertices[i].data != v); ++i)
- {
- ;
- }
- return i;
- }
- //打印邻接表
- void printALGraph(ALGraph& G)
- {
- int i = 0;
- ArcNode* pMove = NULL;
- for (i = 0; i < G.vexnum; i++)
- {
- printf("\n第%d个顶点为:%c", i + 1, G.vertices[i].data);
- pMove = G.vertices[i].firstarc;
- if (pMove)
- {
- printf("\n与第%d个顶点相邻接的每个顶点在图中的位置(下标值)为:", i + 1);
- while (pMove)
- {
- printf("%d ", pMove->adjvex);
- pMove = pMove->nextarc;
- }
- }
- else
- {
- printf("\n没有与第%d个顶点相邻接的顶点。", i + 1);
- }
- }
- }
复制代码


一个图的毗邻矩阵表现是唯一的,但其毗邻表表现不唯一。
不改变图中每个顶点的命名方式,也不改变图的边(每条边的起尽头),
仅改变边的输入序次时,图的毗邻表中每个顶点背面边表中的结点排序方式会发生变化。
由于图中的顶点没变,边也没变,每个顶点及其边表中的内容不会发生变化。
接纳毗邻表表现法创建有向图
- //采用邻接表表示法创建有向图
- #include <stdio.h>
- #include <stdlib.h>
- #define MVNum 100
- typedef int OtherInfo; //假设在边结点中的数据域存储边的权值,且边的权值类型为整型
- typedef char VerTexType; //假设顶点的数据类型为字符型
- typedef struct ArcNode
- {
- int adjvex;
- struct ArcNode* nextarc;
- OtherInfo info;
- }ArcNode; //边结点
- typedef struct VNode
- {
- VerTexType data;
- ArcNode* firstarc;
- }VNode, AdjList[MVNum]; //表头结点
- typedef struct
- {
- AdjList vertices; //存储所有顶点
- int vexnum; //顶点总数
- int arcnum; //总边数
- }ALGraph; //图的信息
- void CreateDG(ALGraph& G);
- int LocateVex(ALGraph& G, VerTexType v);
- void printALGraph(ALGraph& G);
- int main()
- {
- ALGraph G = { {'\0',NULL}, 0,0 };
- CreateDG(G);
- printALGraph(G);
- return 0;
- }
- //采用邻接表表示法创建有向图
- void CreateDG(ALGraph& G)
- {
- int i = 0;
- int k = 0;
- VerTexType v1 = 0;
- VerTexType v2 = 0;
- int j = 0;
- ArcNode* p1 = NULL;
- ArcNode* p2 = NULL;
- printf("请输入有向图的总顶点数:");
- scanf_s(" %d", &G.vexnum);
- printf("请输入有向图的总边数:");
- scanf_s(" %d", &G.arcnum);
- for (i = 0; i < G.vexnum; ++i)
- {
- printf("请输入第%d个顶点的值:", i + 1);
- scanf_s(" %c", &(G.vertices[i].data));
- G.vertices[i].firstarc = NULL; //初始化
- }
- for (k = 0; k < G.arcnum; k++)
- {
- printf("请输入第%d条边依附的两个顶点(用空格间隔,输入结束后按回车): ", k + 1);
- scanf_s(" %c %c", &v1, sizeof(VerTexType), &v2, sizeof(VerTexType));
- i = LocateVex(G, v1);
- j = LocateVex(G, v2);
- p1 = (ArcNode*)malloc(sizeof(ArcNode));
- p1->adjvex = j;
- p1->nextarc = G.vertices[i].firstarc;
- G.vertices[i].firstarc = p1; //将新结点*p1插入顶点Vi的边表头部
- }
- }
- //在G的顶点表vexs中获取字符v的下标(数组G.vexs的下标从0开始)
- int LocateVex(ALGraph& G, VerTexType v)
- {
- int i = 0;
- for (i = 0; i < G.vexnum && (G.vertices[i].data != v); ++i)
- {
- ;
- }
- return i;
- }
- //打印邻接表
- void printALGraph(ALGraph& G)
- {
- int i = 0;
- ArcNode* pMove = NULL;
- for (i = 0; i < G.vexnum; i++)
- {
- printf("\n第%d个顶点为:%c", i + 1, G.vertices[i].data);
- pMove = G.vertices[i].firstarc;
- if (pMove)
- {
- printf("\n将第%d个顶点作为出度,与其相邻接的每个顶点在图中的位置(下标值)为:", i + 1);
- while (pMove)
- {
- printf("%d ", pMove->adjvex);
- pMove = pMove->nextarc;
- }
- }
- else
- {
- printf("\n将第%d个顶点作为出度,没有与其相邻接的顶点。", i + 1);
- }
- }
- }
复制代码


创建有向图的逆毗邻表
- //创建有向图的逆邻接表
- #include <stdio.h>
- #include <stdlib.h>
- #define MVNum 100
- typedef int OtherInfo; //假设在边结点中的数据域存储边的权值,且边的权值类型为整型
- typedef char VerTexType; //假设顶点的数据类型为字符型
- typedef struct ArcNode
- {
- int adjvex;
- struct ArcNode* nextarc;
- OtherInfo info;
- }ArcNode; //边结点
- typedef struct VNode
- {
- VerTexType data;
- ArcNode* firstarc;
- }VNode, AdjList[MVNum]; //表头结点
- typedef struct
- {
- AdjList vertices; //存储所有顶点
- int vexnum; //顶点总数
- int arcnum; //总边数
- }ALGraph; //图的信息
- void CreateDG(ALGraph& G);
- int LocateVex(ALGraph& G, VerTexType v);
- void printALGraph(ALGraph& G);
- int main()
- {
- ALGraph G = { {'\0',NULL}, 0,0 };
- CreateDG(G);
- printALGraph(G);
- return 0;
- }
- //创建有向图的逆邻接表
- void CreateDG(ALGraph& G)
- {
- int i = 0;
- int k = 0;
- VerTexType v1 = 0;
- VerTexType v2 = 0;
- int j = 0;
- ArcNode* p1 = NULL;
- ArcNode* p2 = NULL;
- printf("请输入有向图的总顶点数:");
- scanf_s(" %d", &G.vexnum);
- printf("请输入有向图的总边数:");
- scanf_s(" %d", &G.arcnum);
- for (i = 0; i < G.vexnum; ++i)
- {
- printf("请输入第%d个顶点的值:", i + 1);
- scanf_s(" %c", &(G.vertices[i].data));
- G.vertices[i].firstarc = NULL; //初始化
- }
- for (k = 0; k < G.arcnum; k++)
- {
- printf("请输入第%d条边依附的两个顶点(用空格间隔,输入结束后按回车): ", k + 1);
- scanf_s(" %c %c", &v1, sizeof(VerTexType), &v2, sizeof(VerTexType));
- i = LocateVex(G, v1);
- j = LocateVex(G, v2);
- p1 = (ArcNode*)malloc(sizeof(ArcNode));
- p1->adjvex = i;
- p1->nextarc = G.vertices[j].firstarc;
- G.vertices[j].firstarc = p1; //将新结点*p1插入顶点Vj的边表头部
- }
- }
- //在G的顶点表vexs中获取字符v的下标(数组G.vexs的下标从0开始)
- int LocateVex(ALGraph& G, VerTexType v)
- {
- int i = 0;
- for (i = 0; i < G.vexnum && (G.vertices[i].data != v); ++i)
- {
- ;
- }
- return i;
- }
- //打印逆邻接表
- void printALGraph(ALGraph& G)
- {
- int i = 0;
- ArcNode* pMove = NULL;
- for (i = 0; i < G.vexnum; i++)
- {
- printf("\n第%d个顶点为:%c", i + 1, G.vertices[i].data);
- pMove = G.vertices[i].firstarc;
- if (pMove)
- {
- printf("\n将第%d个顶点作为入度,与其相邻接的每个顶点在图中的位置(下标值)为:", i + 1);
- while (pMove)
- {
- printf("%d ", pMove->adjvex);
- pMove = pMove->nextarc;
- }
- }
- else
- {
- printf("\n将第%d个顶点作为入度,没有与其相邻接的顶点。", i + 1);
- }
- }
- }
复制代码

接纳毗邻表表现法创建无向网
- #include <stdio.h>
- #include <stdlib.h>
- #define MVNum 100
- typedef int OtherInfo; //假设在边结点中的数据域存储边的权值,且边的权值类型为整型
- typedef char VerTexType; //假设顶点的数据类型为字符型
- typedef struct ArcNode
- {
- int adjvex;
- struct ArcNode* nextarc;
- OtherInfo info;
- }ArcNode; //边结点
- typedef struct VNode
- {
- VerTexType data;
- ArcNode* firstarc;
- }VNode, AdjList[MVNum]; //表头结点
- typedef struct
- {
- AdjList vertices; //存储所有顶点
- int vexnum; //顶点总数
- int arcnum; //总边数
- }ALGraph; //图的信息
- void CreateUDN(ALGraph& G);
- int LocateVex(ALGraph& G, VerTexType v);
- void printALGraph(ALGraph& G);
- int main()
- {
- ALGraph G = { {'\0',NULL}, 0,0 };
- CreateUDN(G);
- printALGraph(G);
- return 0;
- }
- //采用邻接表表示法创建无向网
- void CreateUDN(ALGraph& G)
- {
- int i = 0;
- int k = 0;
- VerTexType v1 = 0;
- VerTexType v2 = 0;
- int j = 0;
- ArcNode* p1 = NULL;
- ArcNode* p2 = NULL;
- int w = 0;
- printf("请输入无向网的总顶点数:");
- scanf_s(" %d", &G.vexnum);
- printf("请输入无向网的总边数:");
- scanf_s(" %d", &G.arcnum);
- for (i = 0; i < G.vexnum; ++i)
- {
- printf("请输入第%d个顶点的值:", i + 1);
- scanf_s(" %c", &(G.vertices[i].data));
- G.vertices[i].firstarc = NULL; //初始化
- }
- for (k = 0; k < G.arcnum; k++)
- {
- printf("请输入第%d条边依附的两个顶点(用空格间隔,输入结束后按回车): ", k + 1);
- scanf_s(" %c %c", &v1, sizeof(VerTexType), &v2, sizeof(VerTexType));
- printf("请输入第%d条边的权值 : ", k + 1);
- scanf_s(" %d", &w, sizeof(OtherInfo));
- i = LocateVex(G, v1);
- j = LocateVex(G, v2);
- p1 = (ArcNode*)malloc(sizeof(ArcNode));
- p1->adjvex = j;
- p1->info = w;
- p1->nextarc = G.vertices[i].firstarc;
- G.vertices[i].firstarc = p1; //将新结点*p1插入顶点Vi的边表头部
- p2 = (ArcNode*)malloc(sizeof(ArcNode));
- p2->adjvex = i;
- p1->info = w;
- p2->nextarc = G.vertices[j].firstarc;
- G.vertices[j].firstarc = p2; //将与*p1对称的新的边结点*p2插入顶点Vj的边表头部
- }
- }
- //在G的顶点表vexs中获取字符v的下标(数组G.vexs的下标从0开始)
- int LocateVex(ALGraph& G, VerTexType v)
- {
- int i = 0;
- for (i = 0; i < G.vexnum && (G.vertices[i].data != v); ++i)
- {
- ;
- }
- return i;
- }
- //打印邻接表
- void printALGraph(ALGraph& G)
- {
- int i = 0;
- ArcNode* pMove = NULL;
- for (i = 0; i < G.vexnum; i++)
- {
- printf("\n第%d个顶点为:%c", i + 1, G.vertices[i].data);
- pMove = G.vertices[i].firstarc;
- if (pMove)
- {
- printf("\n与第%d个顶点相邻接的每个顶点在网中的位置(下标值)为:", i + 1);
- while (pMove)
- {
- printf("%d ", pMove->adjvex);
- pMove = pMove->nextarc;
- }
- }
- else
- {
- printf("\n没有与第%d个顶点相邻接的顶点。", i + 1);
- }
- }
- }
复制代码

接纳毗邻表表现法创建有向网
- #include <stdio.h>
- #include <stdlib.h>
- #define MVNum 100
- typedef int OtherInfo; //假设在边结点中的数据域存储边的权值,且边的权值类型为整型
- typedef char VerTexType; //假设顶点的数据类型为字符型
- typedef struct ArcNode
- {
- int adjvex;
- struct ArcNode* nextarc;
- OtherInfo info;
- }ArcNode; //边结点
- typedef struct VNode
- {
- VerTexType data;
- ArcNode* firstarc;
- }VNode, AdjList[MVNum]; //表头结点
- typedef struct
- {
- AdjList vertices; //存储所有顶点
- int vexnum; //顶点总数
- int arcnum; //总边数
- }ALGraph; //图的信息
- void CreateDN(ALGraph& G);
- int LocateVex(ALGraph& G, VerTexType v);
- void printALGraph(ALGraph& G);
- int main()
- {
- ALGraph G = { {'\0',NULL}, 0,0 };
- CreateDN(G);
- printALGraph(G);
- return 0;
- }
- //采用邻接表表示法创建有向网
- void CreateDN(ALGraph& G)
- {
- int i = 0;
- int k = 0;
- VerTexType v1 = 0;
- VerTexType v2 = 0;
- int j = 0;
- ArcNode* p1 = NULL;
- ArcNode* p2 = NULL;
- int w = 0;
- printf("请输入有向网的总顶点数:");
- scanf_s(" %d", &G.vexnum);
- printf("请输入有向网的总边数:");
- scanf_s(" %d", &G.arcnum);
- for (i = 0; i < G.vexnum; ++i)
- {
- printf("请输入第%d个顶点的值:", i + 1);
- scanf_s(" %c", &(G.vertices[i].data));
- G.vertices[i].firstarc = NULL; //初始化
- }
- for (k = 0; k < G.arcnum; k++)
- {
- printf("请输入第%d条边依附的两个顶点(用空格间隔,输入结束后按回车): ", k + 1);
- scanf_s(" %c %c", &v1, sizeof(VerTexType), &v2, sizeof(VerTexType));
- printf("请输入第%d条边的权值 : ", k + 1);
- scanf_s(" %d", &w, sizeof(OtherInfo));
- i = LocateVex(G, v1);
- j = LocateVex(G, v2);
- p1 = (ArcNode*)malloc(sizeof(ArcNode));
- p1->adjvex = j;
- p1->info = w;
- p1->nextarc = G.vertices[i].firstarc;
- G.vertices[i].firstarc = p1; //将新结点*p1插入顶点Vi的边表头部
- }
- }
- //在G的顶点表vexs中获取字符v的下标(数组G.vexs的下标从0开始)
- int LocateVex(ALGraph& G, VerTexType v)
- {
- int i = 0;
- for (i = 0; i < G.vexnum && (G.vertices[i].data != v); ++i)
- {
- ;
- }
- return i;
- }
- //打印邻接表
- void printALGraph(ALGraph& G)
- {
- int i = 0;
- ArcNode* pMove = NULL;
- for (i = 0; i < G.vexnum; i++)
- {
- printf("\n第%d个顶点为:%c", i + 1, G.vertices[i].data);
- pMove = G.vertices[i].firstarc;
- if (pMove)
- {
- printf("\n将第%d个顶点作为出度,与其相邻接的每个顶点在网中的位置(下标值)为:", i + 1);
- while (pMove)
- {
- printf("%d ", pMove->adjvex);
- pMove = pMove->nextarc;
- }
- }
- else
- {
- printf("\n将第%d个顶点作为出度,没有与第%d个顶点相邻接的顶点。", i + 1);
- }
- }
- }
复制代码

创建有向网的逆毗邻表
- #include <stdio.h>
- #include <stdlib.h>
- #define MVNum 100
- typedef int OtherInfo; //假设在边结点中的数据域存储边的权值,且边的权值类型为整型
- typedef char VerTexType; //假设顶点的数据类型为字符型
- typedef struct ArcNode
- {
- int adjvex;
- struct ArcNode* nextarc;
- OtherInfo info;
- }ArcNode; //边结点
- typedef struct VNode
- {
- VerTexType data;
- ArcNode* firstarc;
- }VNode, AdjList[MVNum]; //表头结点
- typedef struct
- {
- AdjList vertices; //存储所有顶点
- int vexnum; //顶点总数
- int arcnum; //总边数
- }ALGraph; //图的信息
- void CreateDN(ALGraph& G);
- int LocateVex(ALGraph& G, VerTexType v);
- void printALGraph(ALGraph& G);
- int main()
- {
- ALGraph G = { {'\0',NULL}, 0,0 };
- CreateDN(G);
- printALGraph(G);
- return 0;
- }
- //创建有向网的逆邻接表
- void CreateDN(ALGraph& G)
- {
- int i = 0;
- int k = 0;
- VerTexType v1 = 0;
- VerTexType v2 = 0;
- int j = 0;
- ArcNode* p1 = NULL;
- ArcNode* p2 = NULL;
- int w = 0;
- printf("请输入有向网的总顶点数:");
- scanf_s(" %d", &G.vexnum);
- printf("请输入有向网的总边数:");
- scanf_s(" %d", &G.arcnum);
- for (i = 0; i < G.vexnum; ++i)
- {
- printf("请输入第%d个顶点的值:", i + 1);
- scanf_s(" %c", &(G.vertices[i].data));
- G.vertices[i].firstarc = NULL; //初始化
- }
- for (k = 0; k < G.arcnum; k++)
- {
- printf("请输入第%d条边依附的两个顶点(用空格间隔,输入结束后按回车): ", k + 1);
- scanf_s(" %c %c", &v1, sizeof(VerTexType), &v2, sizeof(VerTexType));
- printf("请输入第%d条边的权值 : ", k + 1);
- scanf_s(" %d", &w, sizeof(OtherInfo));
- i = LocateVex(G, v1);
- j = LocateVex(G, v2);
- p1 = (ArcNode*)malloc(sizeof(ArcNode));
- p1->adjvex = i;
- p1->info = w;
- p1->nextarc = G.vertices[j].firstarc;
- G.vertices[j].firstarc = p1; //将新结点*p1插入顶点Vj的边表头部
- }
- }
- //在G的顶点表vexs中获取字符v的下标(数组G.vexs的下标从0开始)
- int LocateVex(ALGraph& G, VerTexType v)
- {
- int i = 0;
- for (i = 0; i < G.vexnum && (G.vertices[i].data != v); ++i)
- {
- ;
- }
- return i;
- }
- //打印逆邻接表
- void printALGraph(ALGraph& G)
- {
- int i = 0;
- ArcNode* pMove = NULL;
- for (i = 0; i < G.vexnum; i++)
- {
- printf("\n第%d个顶点为:%c", i + 1, G.vertices[i].data);
- pMove = G.vertices[i].firstarc;
- if (pMove)
- {
- printf("\n将第%d个顶点作为入度,与其相邻接的每个顶点在网中的位置(下标值)为:", i + 1);
- while (pMove)
- {
- printf("%d ", pMove->adjvex);
- pMove = pMove->nextarc;
- }
- }
- else
- {
- printf("\n将第%d个顶点作为入度,没有与第%d个顶点相邻接的顶点。", i + 1);
- }
- }
- }
复制代码
6.4.3 十字链表
接纳十字链表表现法创建有向图
- //采用十字链表表示法创建有向图
- #include <stdio.h>
- #include <stdlib.h>
- #define MAX_VERTEX_NUM 20
- typedef int InfoType; //假设在边结点中的数据域存储边的权值,且边的权值类型为整型
- typedef char VerTexType; //假设顶点的数据类型为字符型
- typedef struct ArcBox
- {
- int tailvext;
- int headvex;
- struct ArcBox* hlink;
- struct ArcBox* tlink;
- InfoType *info;
- }ArcBox;
- typedef struct VexNode
- {
- VerTexType data;
- ArcBox *firstin;
- ArcBox *firstout;
- }VexNode;
- typedef struct
- {
- VexNode xlist[MAX_VERTEX_NUM]; //表头向量
- int vexnum; //顶点总数
- int arcnum; //总边数
- }OLGraph; //图的信息
- void CreateOLGraph(OLGraph& G);
- int LocateVex(OLGraph& G, VerTexType v);
- void printOLGraph(OLGraph& G);
- int main()
- {
- OLGraph G = { {'\0',NULL,NULL}, 0,0 };
- CreateOLGraph(G);
- printOLGraph(G);
- return 0;
- }
- //采用十字链表表示法创建有向图
- void CreateOLGraph(OLGraph& G)
- {
- int i = 0;
- int j = 0;
- int k = 0;
- VerTexType v1 = 0;
- VerTexType v2 = 0;
- ArcBox* p1 = NULL;
- printf("请输入有向图的总顶点数:");
- scanf_s(" %d", &G.vexnum);
- printf("请输入有向图的总边数:");
- scanf_s(" %d", &G.arcnum);
- for (i = 0; i < G.vexnum; ++i)
- {
- printf("请输入第%d个顶点的值:", i + 1);
- scanf_s(" %c", &(G.xlist[i].data));
- G.xlist[i].firstin = NULL;
- G.xlist[i].firstout = NULL;//初始化
- }
- for (k = 0; k < G.arcnum; k++)
- {
- printf("请输入第%d条弧依附的两个顶点(用空格间隔,输入结束后按回车): ", k + 1);
- scanf_s(" %c %c", &v1, sizeof(VerTexType), &v2, sizeof(VerTexType));
- //起点v1是弧尾,终点v2是弧头
- //弧<v1,v2>是v1的出度,是v2的入度
- i = LocateVex(G, v1);
- j = LocateVex(G, v2);
- //起点v1是弧尾,下标值为i;终点v2是弧头,下标值为j
- //弧<v1,v2>是第i+1个顶点的出度firstout,是第j+1个顶点的入度firstin
- p1 = (ArcBox*)malloc(sizeof(ArcBox));
- p1->tailvext = i; //起点v1是弧尾,下标值为i
- p1->headvex = j; //终点v2是弧头,下标值为j
- //p1弧结点中的链域tlink指向与其弧尾tailvext相同的下一条弧(即指向第i+1个顶点v1的下一个出度firstout)
- p1->tlink = G.xlist[i].firstout; //p1指向的弧<v1,v2>是第i+1个顶点v1的出度firstout
- G.xlist[i].firstout = p1; //前插法将p1插入到第i+1个顶点v1的出度单链表中
- //p1弧结点中的链域hlink指向与其弧头headvex相同的下一条弧(即指向第j+1个顶点v2的下一个入度firstin)
- p1->hlink = G.xlist[j].firstin; //p1指向的弧<v1,v2>是第j+1个顶点v2的入度firstin
- G.xlist[j].firstin = p1; //前插法将p1插入到第j+1个顶点v2的入度单链表中
- }
- }
- //在G的顶点表xlist中获取字符v的下标(数组G.xlist的下标从0开始)
- int LocateVex(OLGraph& G, VerTexType v)
- {
- int i = 0;
- for (i = 0; i < G.vexnum && (G.xlist[i].data != v); ++i)
- {
- ;
- }
- return i;
- }
- //打印十字链表
- void printOLGraph(OLGraph& G)
- {
- int i = 0;
- ArcBox* pMoveIn = NULL;
- ArcBox* pMoveOut = NULL;
- for (i = 0; i < G.vexnum; i++)
- {
- printf("\n第%d个顶点为:%c", i + 1, G.xlist[i].data);
- pMoveOut = G.xlist[i].firstout;
- if (pMoveOut)
- {
- printf("\n将第%d个顶点作为出度,与其相邻接的每个顶点在图中的位置(下标值)为:", i + 1);
- while (pMoveOut)
- {
- printf("%d ", pMoveOut->headvex);
- pMoveOut = pMoveOut->tlink;
- }
- }
- else
- {
- printf("\n将第%d个顶点作为出度,没有与其相邻接的顶点。", i + 1);
- }
- pMoveIn = G.xlist[i].firstin;
- if (pMoveIn)
- {
- printf("\n将第%d个顶点作为入度,与其相邻接的每个顶点在图中的位置(下标值)为:", i + 1);
- while (pMoveIn)
- {
- printf("%d ", pMoveIn->tailvext);
- pMoveIn = pMoveIn->hlink;
- }
- }
- else
- {
- printf("\n将第%d个顶点作为入度,没有与其相邻接的顶点。", i + 1);
- }
- }
- }
复制代码

该有向图的毗邻矩阵,其中各行、各列中不为0的元素,与其十字链表每个顶点的出度、入度效果有对应关系。

接纳十字链表表现法创建有向网
输入并读取权值,赋值到 弧结点 ArcBox 布局中的 info 成员即可。
- //采用十字链表表示法创建有向网
- void CreateOLGraph(OLGraph& G)
- {
- int i = 0;
- int j = 0;
- int k = 0;
- VerTexType v1 = 0;
- VerTexType v2 = 0;
- ArcBox* p1 = NULL;
- int* w = 0;
- printf("请输入有向网的总顶点数:");
- scanf_s(" %d", &G.vexnum);
- printf("请输入有向网的总边数:");
- scanf_s(" %d", &G.arcnum);
- for (i = 0; i < G.vexnum; ++i)
- {
- printf("请输入第%d个顶点的值:", i + 1);
- scanf_s(" %c", &(G.xlist[i].data));
- G.xlist[i].firstin = NULL;
- G.xlist[i].firstout = NULL;//初始化
- }
- for (k = 0; k < G.arcnum; k++)
- {
- printf("请输入第%d条弧依附的两个顶点(用空格间隔,输入结束后按回车): ", k + 1);
- scanf_s(" %c %c", &v1, sizeof(VerTexType), &v2, sizeof(VerTexType));
- printf("请输入第%d条边的权值 : ", k + 1);
- scanf_s(" %d", w, sizeof(InfoType)); //在ArcBox中,info由指向int的指针定义
- i = LocateVex(G, v1);
- j = LocateVex(G, v2);
- p1 = (ArcBox*)malloc(sizeof(ArcBox));
- p1->tailvext = i;
- p1->headvex = j;
- p1->info = w; //赋值到弧结点p1中的info成员
- p1->tlink = G.xlist[i].firstout;
- G.xlist[i].firstout = p1;
- p1->hlink = G.xlist[j].firstin;
- G.xlist[j].firstin = p1;
- }
- }
复制代码 6.4.4 毗邻多重表
接纳毗邻多重表表现法创建无向图
- //采用邻接多重表表示法创建无向图
- #include <stdio.h>
- #include <stdlib.h>
- #define MAX_VERTEX_NUM 20
- typedef enum {unvisited,visited} VisitIf;
- typedef int InfoType; //假设在边结点中的数据域存储边的权值,且边的权值类型为整型
- typedef char VerTexType; //假设顶点的数据类型为字符型
- typedef struct EBox
- {
- VisitIf mark;
- int ivex;
- int jvex;
- struct EBox* ilink;
- struct EBox* jlink;
- InfoType *info;
- }EBox;
- typedef struct VexBox
- {
- VerTexType data;
- EBox* firstedge;
- }VexBox;
- typedef struct
- {
- VexBox adjmulist[MAX_VERTEX_NUM]; //表头向量
- int vexnum; //顶点总数
- int edgenum; //总边数
- }AMLGraph; //图的信息
- void CreateAMLGraph(AMLGraph& G);
- int LocateVex(AMLGraph& G, VerTexType v);
- void printAMLGraph(AMLGraph& G);
- int main()
- {
- AMLGraph G = { {'\0',NULL,NULL}, 0,0 };
- CreateAMLGraph(G);
- printAMLGraph(G);
- return 0;
- }
- //采用邻接多重表表示法创建无向图
- void CreateAMLGraph(AMLGraph& G)
- {
- int i = 0;
- int j = 0;
- int k = 0;
- VerTexType v1 = 0;
- VerTexType v2 = 0;
- EBox* p1 = NULL;
- printf("请输入无向图的总顶点数:");
- scanf_s(" %d", &G.vexnum);
- printf("请输入无向图的总边数:");
- scanf_s(" %d", &G.edgenum);
- for (i = 0; i < G.vexnum; ++i)
- {
- printf("请输入第%d个顶点的值:", i + 1);
- scanf_s(" %c", &(G.adjmulist[i].data));
- G.adjmulist[i].firstedge = NULL; //初始化
- }
- for (k = 0; k < G.edgenum; k++)
- {
- printf("请输入第%d条弧依附的两个顶点(用空格间隔,输入结束后按回车): ", k + 1);
- scanf_s(" %c %c", &v1, sizeof(VerTexType), &v2, sizeof(VerTexType));
-
- i = LocateVex(G, v1);
- j = LocateVex(G, v2);
- p1 = (EBox*)malloc(sizeof(EBox));
- p1->ivex = i;
- p1->jvex = j;
- p1->ilink = G.adjmulist[i].firstedge;
- G.adjmulist[i].firstedge = p1;
- p1->jlink = G.adjmulist[j].firstedge;
- G.adjmulist[j].firstedge = p1;
- }
- }
- //在G的顶点表adjmulist中获取字符v的下标(数组G.xlist的下标从0开始)
- int LocateVex(AMLGraph& G, VerTexType v)
- {
- int i = 0;
- for (i = 0; i < G.vexnum && (G.adjmulist[i].data != v); ++i)
- {
- ;
- }
- return i;
- }
- //打印邻接多重表
- void printAMLGraph(AMLGraph& G)
- {
- int i = 0;
- EBox* pMove = NULL;
- for (i = 0; i < G.vexnum; i++)
- {
- printf("\n第%d个顶点为:%c", i + 1, G.adjmulist[i].data);
- pMove = G.adjmulist[i].firstedge;
- if (pMove)
- {
- printf("\n与第%d个顶点相邻接的每个顶点在图中的位置(下标值)为:", i + 1);
- while (pMove)
- {
- if (pMove->ivex == i)
- {
- printf("%d ", pMove->jvex);
- pMove = pMove->ilink;
- }
- else if (pMove->jvex == i)
- {
- printf("%d ", pMove->ivex);
- pMove = pMove->jlink;
- }
- }
- }
- else
- {
- printf("\n没有与第%d个顶点相邻接的顶点。", i + 1);
- }
- }
- }
复制代码


接纳毗邻多重表表现法创建无向网
输入并读取权值,赋值到 边结点 EBox 布局中的 info 成员即可。
- //采用邻接多重表表示法创建无向网
- void CreateAMLGraph(AMLGraph& G)
- {
- int i = 0;
- int j = 0;
- int k = 0;
- VerTexType v1 = 0;
- VerTexType v2 = 0;
- EBox* p1 = NULL;
- int* w = 0;
- printf("请输入无向网的总顶点数:");
- scanf_s(" %d", &G.vexnum);
- printf("请输入无向网的总边数:");
- scanf_s(" %d", &G.edgenum);
- for (i = 0; i < G.vexnum; ++i)
- {
- printf("请输入第%d个顶点的值:", i + 1);
- scanf_s(" %c", &(G.adjmulist[i].data));
- G.adjmulist[i].firstedge = NULL; //初始化
- }
- for (k = 0; k < G.edgenum; k++)
- {
- printf("请输入第%d条弧依附的两个顶点(用空格间隔,输入结束后按回车): ", k + 1);
- scanf_s(" %c %c", &v1, sizeof(VerTexType), &v2, sizeof(VerTexType));
- printf("请输入第%d条边的权值 : ", k + 1);
- scanf_s(" %d", w, sizeof(InfoType)); //在EBox中,info由指向int的指针定义
- i = LocateVex(G, v1);
- j = LocateVex(G, v2);
- p1 = (EBox*)malloc(sizeof(EBox));
- p1->ivex = i;
- p1->jvex = j;
- p1->info = w; //赋值到边结点p1中的info成员
- p1->ilink = G.adjmulist[i].firstedge;
- G.adjmulist[i].firstedge = p1;
- p1->jlink = G.adjmulist[j].firstedge;
- G.adjmulist[j].firstedge = p1;
- }
- }
复制代码 免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |