一、图的抽象数据类型定义
vexs[i]表示第i个下标所表示的元素
arcs表示图的邻接矩阵
vexnum表示顶点数,边数
vis数组用来看该点是否被遍历过
typedef char VertexType;
typedef int Status;
typedef struct {
VertexType vexs[MAX_VERTEX_NUM];
int arcs[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
int vexnum, arcnum;
}MGraph;
int vis[MAX_VERTEX_NUM] = { 0 };
二、图的创建
Status CreateDN(MGraph& G)
{
for (int i = 0; i < MAX_VERTEX_NUM; i++)
{
for (int j = 0; j < MAX_VERTEX_NUM; j++)
{
if (i == j)G.arcs[i][j] = 0;
else G.arcs[i][j] = INFINITY;
}
}
char c;
printf("请输入图的结点个数:");
scanf("%d", &G.vexnum);
c = getchar();
printf("请输入图的边的个数:");
scanf("%d", &G.arcnum);
c = getchar();
printf("请输入各个顶点:");
for (int i = 1; i <= G.vexnum; i++)
{
scanf("%c", &G.vexs[i]);
}
c = getchar();
VertexType char1, char2;
int weight;
printf("请输入各个边(eg.AB 12):\n");
for (int i = 1; i <= G.arcnum; i++)
{
scanf("%c%c", &char1, &char2);
c = getchar();
scanf("%d", &weight);
c = getchar();
int p = Locate(G, char1);
int q = Locate(G, char2);
if (p == -1 || q == -1)return false;
G.arcs[p][q] = G.arcs[q][p] = weight;
}
return true;
}
其中Locate函数的作用是根据字符找到下标
具体函数代码如下:
int Locate(MGraph G, VertexType c)
{
for (int i = 1; i <= G.vexnum; i++)
{
if (c == G.vexs[i])
return i;
}
return -1;
}
打印图的邻接矩阵
void Print(MGraph G)
{
printf(" ");
for (int i = 1; i <= G.vexnum; i++)
{
printf("%c\t", G.vexs[i]);
}
puts("");
for (int i = 1; i <= G.vexnum; i++)
{
printf("%c ", G.vexs[i]);
for (int j = 1; j <= G.vexnum; j++)
{
if (G.arcs[i][j] != INFINITY)printf("%d\t", G.arcs[i][j]);
else printf("∞\t");
}
puts("");
}
}
三、图的深度优先遍历
在遍历时,注意遍历过的元素用vis数组标记上
void DFS(MGraph G,int t)
{
vis[t] = 1;
printf("%c ", G.vexs[t]);
for (int i = 1; i <= G.vexnum; i++)
if (G.arcs[t][i] != INFINITY && !vis[i])
DFS(G, i);
}
四、图的广度优先遍历
遍历所用到的数据结构——队列
队列的相关操作如下:
void InitQueue(Queue& q)
{
q.base = (VertexType*)malloc(sizeof(VertexType)*MAX_VERTEX_NUM);
q.front = q.rear = 0;
q.queuesize = MAX_VERTEX_NUM;
}
void EnQueue(Queue& q, VertexType c)
{
if ((q.rear + 1) % MAX_VERTEX_NUM == q.front)return;
q.base[q.rear] = c;
q.rear = (q.rear + 1) % MAX_VERTEX_NUM;
}
VertexType DeQueue(Queue& q)
{
if (q.rear == q.front)return 0;
VertexType e = q.base[q.front];
q.front = (q.front + 1) % MAX_VERTEX_NUM;
return e;
}
代码如下:
void BFS(MGraph G)
{
Queue q;
memset(vis, 0, sizeof vis);
InitQueue(q);
EnQueue(q, G.vexs[1]);
vis[1] = 1;
while (q.rear != q.front)
{
char c = DeQueue(q);
printf("%c ", c);
int now = Locate(G, c);
for (int i = 1; i <= G.vexnum; i++)
{
if (G.arcs[now][i] != INFINITY && !vis[i])
{
EnQueue(q, G.vexs[i]);
vis[i] = 1;
}
}
}
}
五、拓扑排序
Status TopSort(MGraph G)
{
int in[MAX_VERTEX_NUM] = { 0 };
for (int i = 1; i < G.vexnum; i++)
for (int j = 1; j <= G.vexnum; j++)
if (G.arcs[i][j] != INFINITY && G.arcs[i][j])
in[j]++;
Queue q;
InitQueue(q);
for (int i = 1; i <= G.vexnum; i++)
if (!in[i])
EnQueue(q, G.vexs[i]);
int cnt = 0;
while (q.front != q.rear)
{
char c = DeQueue(q);
int now = Locate(G, c);
cnt++;
for (int i = 1; i <= G.vexnum; i++)
{
if (G.arcs[now][i] != INFINITY && G.arcs[now][i])
{
if (!(--in[i]))
EnQueue(q, G.vexs[i]);
}
}
}
if (cnt < G.vexnum)
{
printf("此图不存在拓扑序列\n");
return false;
}
else
{
printf("这个图的拓扑排序序列为:\n");
for (int i = 0; i < G.vexnum; i++)
printf("%c ", q.base[i]);
}
}
六、总代码及运行结果展示
总代码:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define INFINITY 0x3f3f3f3f
#define MAX_VERTEX_NUM 50
typedef char VertexType;
typedef int Status;
typedef struct {
VertexType vexs[MAX_VERTEX_NUM];
int arcs[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
int vexnum, arcnum;
}MGraph;
typedef struct {
VertexType* base;
int front;
int rear;
int queuesize;
}Queue;
int vis[MAX_VERTEX_NUM] = { 0 };
void InitQueue(Queue& q)
{
q.base = (VertexType*)malloc(sizeof(VertexType)*MAX_VERTEX_NUM);
q.front = q.rear = 0;
q.queuesize = MAX_VERTEX_NUM;
}
void EnQueue(Queue& q, VertexType c)
{
if ((q.rear + 1) % MAX_VERTEX_NUM == q.front)return;
q.base[q.rear] = c;
q.rear = (q.rear + 1) % MAX_VERTEX_NUM;
}
VertexType DeQueue(Queue& q)
{
if (q.rear == q.front)return 0;
VertexType e = q.base[q.front];
q.front = (q.front + 1) % MAX_VERTEX_NUM;
return e;
}
int Locate(MGraph G, VertexType c)
{
for (int i = 1; i <= G.vexnum; i++)
{
if (c == G.vexs[i])
return i;
}
return -1;
}
Status CreateDN(MGraph& G)
{
for (int i = 0; i < MAX_VERTEX_NUM; i++)
{
for (int j = 0; j < MAX_VERTEX_NUM; j++)
{
if (i == j)G.arcs[i][j] = 0;
else G.arcs[i][j] = INFINITY;
}
}
char c;
printf("请输入图的结点个数:");
scanf("%d", &G.vexnum);
c = getchar();
printf("请输入图的边的个数:");
scanf("%d", &G.arcnum);
c = getchar();
printf("请输入各个顶点:");
for (int i = 1; i <= G.vexnum; i++)
{
scanf("%c", &G.vexs[i]);
}
c = getchar();
VertexType char1, char2;
int weight;
printf("请输入各个边(eg.AB 12):\n");
for (int i = 1; i <= G.arcnum; i++)
{
scanf("%c%c", &char1, &char2);
c = getchar();
scanf("%d", &weight);
c = getchar();
int p = Locate(G, char1);
int q = Locate(G, char2);
if (p == -1 || q == -1)return false;
//G.arcs[p][q] = G.arcs[q][p] = weight;//无向图
G.arcs[p][q] = weight;//有向图
}
return true;
}
void Print(MGraph G)
{
printf(" ");
for (int i = 1; i <= G.vexnum; i++)
{
printf("%c\t", G.vexs[i]);
}
puts("");
for (int i = 1; i <= G.vexnum; i++)
{
printf("%c ", G.vexs[i]);
for (int j = 1; j <= G.vexnum; j++)
{
if (G.arcs[i][j] != INFINITY)printf("%d\t", G.arcs[i][j]);
else printf("∞\t");
}
puts("");
}
}
void DFS(MGraph G,int t)
{
vis[t] = 1;
printf("%c ", G.vexs[t]);
for (int i = 1; i <= G.vexnum; i++)
if (G.arcs[t][i] != INFINITY && !vis[i])
DFS(G, i);
}
void BFS(MGraph G)
{
Queue q;
memset(vis, 0, sizeof vis);
InitQueue(q);
EnQueue(q, G.vexs[1]);
vis[1] = 1;
while (q.rear != q.front)
{
char c = DeQueue(q);
printf("%c ", c);
int now = Locate(G, c);
for (int i = 1; i <= G.vexnum; i++)
{
if (G.arcs[now][i] != INFINITY && !vis[i])
{
EnQueue(q, G.vexs[i]);
vis[i] = 1;
}
}
}
}
Status TopSort(MGraph G)
{
int in[MAX_VERTEX_NUM] = { 0 };
for (int i = 1; i < G.vexnum; i++)
for (int j = 1; j <= G.vexnum; j++)
if (G.arcs[i][j] != INFINITY && G.arcs[i][j])
in[j]++;
Queue q;
InitQueue(q);
for (int i = 1; i <= G.vexnum; i++)
if (!in[i])
EnQueue(q, G.vexs[i]);
int cnt = 0;
while (q.front != q.rear)
{
char c = DeQueue(q);
int now = Locate(G, c);
cnt++;
for (int i = 1; i <= G.vexnum; i++)
{
if (G.arcs[now][i] != INFINITY && G.arcs[now][i])
{
if (!(--in[i]))
EnQueue(q, G.vexs[i]);
}
}
}
if (cnt < G.vexnum)
{
printf("此图不存在拓扑序列\n");
return false;
}
else
{
printf("这个图的拓扑排序序列为:\n");
for (int i = 0; i < G.vexnum; i++)
printf("%c ", q.base[i]);
}
}
int main()
{
MGraph G;
char start;
if (CreateDN(G))
{
printf("图创建成功!它的邻接矩阵为:\n");
Print(G);
}
else printf("图创建失败QwQ\n");
printf("这个图的深度优先遍历序列为:\n");
DFS(G, 1); puts("");
printf("这个图的广度优先遍历序列为:\n");
BFS(G); puts("");
TopSort(G);
return 0;
}
样例:
/*
9
11
123456789
12 6
13 4
14 5
25 1
35 1
46 2
57 9
58 7
68 4
79 2
89 4
*/
运行结果: