#include "stdio.h"
#include "string.h"
#define MaxInt 32767 // 表示极大值,即∞
#define MVNum 100 // 最大顶点数
#define VerTexType char // 假设顶点的数据类型为字符型
#define ArcType int // 假设边的权值类型为整型
typedef struct
{
VerTexType vexs[MVNum]; // 顶点表
ArcType arcs[MVNum][MVNum]; // 邻接矩阵
int vexnum, arcnum; // 图的当前点数和边数
} AMGraph, *AMGraph_str;
// 定义队列类型和相关操作
#define QUEUE_SIZE 100
typedef struct
{
char data[QUEUE_SIZE];
char front, rear;
} Queue;
int LocateVex(AMGraph G, VerTexType u);
AMGraph CreateDN(void);
void printf_DN(AMGraph G);
void DN_init(AMGraph *G);
void DN_add_elements(AMGraph *G);
void find_element(AMGraph G);
void main()
{
AMGraph G;
G = CreateDN();
printf_DN(G);
DN_add_elements(&G);
printf_DN(G);
find_element(G);
printf("深度优先遍历:\n");
dfs_traverse(&G);
printf("\n广度优先遍历:\n");
bfs_traverse(&G);
system("pause");
}
void printf_DN(AMGraph G)
{
int i = 0, j = 0;
printf("\n头部总顶点数:%d,总边数:%d\n", G.vexnum, G.arcnum);
printf("打印图的内容:\n ");
for (i = 0; i < G.vexnum; i++)
printf("[%c]", G.vexs[i]);
printf("\n");
for (i = 0; i < G.vexnum; i++)
{
printf("[%c]:", G.vexs[i]);
for (j = 0; j < G.vexnum; j++)
printf("[%c]", G.arcs[i][j] == MaxInt ? 'N' : (G.arcs[i][j] + '0'));
printf("\n");
}
}
void DN_init(AMGraph *G)
{
int i = 0, j = 0;
for (i = 0; i < G->vexnum; i++) // 初始化邻接矩阵,边的权值均置为极大值
for (j = 0; j < G->vexnum; j++)
G->arcs[i][j] = MaxInt;
printf("邻接矩阵初始化完成\n");
// printf_DN(&G);
}
AMGraph CreateDN(void) // 创建有向图
{
AMGraph G;
int i = 0, j = 0, k = 0;
ArcType w = 0;
char data = 0;
char v1 = 0, v2 = 0;
// 采用邻接矩阵表示法,创建有向网G
printf("请输入总顶点数:");
scanf_s("%d", &G.vexnum, 2);
printf("\n请输入总边数:");
scanf("%d", &G.arcnum);
printf("\n总顶点数:%d,总边数:%d\n", G.vexnum, G.arcnum);
printf("请输入各点信息\n");
getchar();
for (i = 0; i < G.vexnum; i++) // 依次输入点的信息
{
printf("[%d]=", i);
fflush(stdin); // 清空缓冲区
scanf("%c", &G.vexs[i]);
printf("\n");
}
DN_init(&G);
printf_DN(G);
printf("开始构造邻接矩阵\n");
printf("请输入连接点与权重,格式:v1,v2,w,方向:v1->v2,权重:w\n");
for (i = 0, j = 0, k = 0; k < G.arcnum; k++)
{ // 构造邻接矩阵
printf("[%d]:", k);
fflush(stdin); // 清空缓冲区
scanf("%c,%c,%d", &v1, &v2, &w);
printf("结果[%C][%c][%d]\n", v1, v2, w);
i = LocateVex(G, v1);
j = LocateVex(G, v2); // 确定v1和v2在G中的位置
printf("arcs[%d][%d]=%d\n", i, j, w);
if (i == -1 || j == -1)
{
printf("该元素不存在");
k--;
}
else
G.arcs[i][j] = w; // 边<v1, v2>的权值置为w
G.arcs[i][j] = w; // 边<v1, v2>的权值置为w
}
return G;
} //
void DN_add_elements(AMGraph *G)
{
int i = 0, j = 0, k = 0, len1 = 0, len2 = 0, w = 0;
char v1 = 0, v2 = 0;
printf("请输入要插入参数个数:");
fflush(stdin); // 清空缓冲区
scanf("%d", &len1);
if (G->vexnum + len1 > MVNum)
{
printf("总顶点数超过限制");
return;
}
G->vexnum += len1;
printf("请输入要添加的边的个数:");
fflush(stdin); // 清空缓冲区
scanf("%d", &len2);
G->arcnum += len2;
printf("\n总顶点数:%d,总边数:%d\n", G->vexnum, G->arcnum);
printf("请输入各点信息\n");
for (i = G->vexnum - len1; i < G->vexnum; i++)
{
printf("[%d]=", i);
fflush(stdin); // 清空缓冲区
scanf("%c", &G->vexs[i]);
}
printf_DN(*G);
printf("请输入连接点与权重,格式:v1,v2,w,方向:v1->v2,权重:w\n");
for (i = 0, j = 0, k = G->arcnum - len2; k < G->arcnum; k++)
{ // 构造邻接矩阵
printf("[%d]:", k);
fflush(stdin); // 清空缓冲区
scanf("%c,%c,%d", &v1, &v2, &w);
printf("结果[%C][%c][%d]\n", v1, v2, w);
i = LocateVex(*G, v1);
j = LocateVex(*G, v2); // 确定v1和v2在G中的位置
printf("arcs[%d][%d]=%d\n", i, j, w);
if (i == -1 || j == -1)
{
printf("该元素不存在");
k--;
}
else
G->arcs[i][j] = w; // 边<v1, v2>的权值置为w
}
}
void find_element(AMGraph G)
{
int i = 0, j = 0;
char key = 0;
printf("请输入要查询的关键字:");
fflush(stdin); // 清空缓冲区
scanf("%c", &key);
i = LocateVex(G, key);
if (i == -1)
{
printf("该元素不存在");
return;
}
printf("查询结果:\n[%c]:", G.vexs[i]);
for (j = 0; j < G.vexnum; j++)
printf("[%c]", G.arcs[i][j] == MaxInt ? 'N' : (G.arcs[i][j] + '0'));
for (j = 0; j < G.vexnum; j++)
{
if (G.arcs[i][j] != MaxInt)
{
printf("\n第一个邻接点是:%c\n", G.vexs[j]);
break;
}
}
}
int LocateVex(AMGraph G, VerTexType u)
{ // 存在则返回u在顶点表中的下标;否则返回-1
int i;
for (i = 0; i < G.vexnum; ++i)
if (u == G.vexs[i])
return i;
return -1;
}
void init_queue(Queue *q)
{
q->front = q->rear = 0;
}
int is_queue_empty(Queue *q)
{
return q->front == q->rear;
}
int enqueue(Queue *q, int x)
{
if ((q->rear + 1) % QUEUE_SIZE == q->front)
{
return 0; // 队列已满
}
q->data[q->rear] = x;
q->rear = (q->rear + 1) % QUEUE_SIZE;
return 1; // 入队成功
}
int dequeue(Queue *q, int *x)
{
if (is_queue_empty(q))
{
return 0; // 队列已空
}
*x = q->data[q->front];
q->front = (q->front + 1) % QUEUE_SIZE;
return 1; // 出队成功
}
// 深度优先遍历
void dfs(int v, int visited[], AMGraph *G)
{
int i;
printf("%c ", G->vexs[v]);
visited[v] = 1;
for (i = 0; i < G->vexnum; i++)
{
if (G->arcs[v][i] != MaxInt && !visited[i])
{
dfs(i, visited, G);
}
}
}
void dfs_traverse(AMGraph *G)
{
int visited[MVNum] = {0};
int i;
char string = 0;
again_DFS:
printf("请输入访问节点:");
fflush(stdin); // 清空缓冲区
scanf("%c", &string);
// 对每个未访问过的节点进行广度优先遍历
i = LocateVex(*G, string);
if (i == -1)
{
printf("输入元素不存在,请重新输入");
goto again_DFS;
}
for (; i < G->vexnum; i++)
{
if (!visited[i])
{
dfs(i, visited, G);
}
}
}
// 广度优先遍历
void bfs_traverse(AMGraph *G)
{
int visited[MVNum] = {0};
Queue q;
int i, v;
char string = 0;
again:
printf("请输入访问节点:");
fflush(stdin); // 清空缓冲区
scanf("%c", &string);
// 对每个未访问过的节点进行广度优先遍历
i = LocateVex(*G, string);
if (i == -1)
{
printf("输入元素不存在,请重新输入");
goto again;
}
for (; i < G->vexnum; i++)
{
if (!visited[i])
{
visited[i] = 1;
printf("%c ", G->vexs[i]);
enqueue(&q, i);
while (!is_queue_empty(&q))
{
dequeue(&q, &v);
for (i = 0; i < G->vexnum; i++)
{
if (G->arcs[v][i] && !visited[i])
{
visited[i] = 1;
printf("%c ", G->vexs[i]);
enqueue(&q, i);
}
}
}
}
}
}
使用案例截图: