#include<stdio.h>
#include<stdlib.h>
#define MaxVertices 100
typedef char DataType;
//建立边表
typedef struct node
{
int adjvex; //指向边表结点
struct node *nextarc; //指向下一条边,没有则为NULL
int info; //权值
}ArcNode;
//建立顶点表
typedef struct
{
DataType data[MaxVertices]; //顶点数据
ArcNode *firstarc; //指向该顶点的第一个边表结点
}VerNode;
//建立图
typedef struct
{
VerNode adjlist[MaxVertices];//顶点数组
int n; //总顶点的个数
int e; //总的边数
}ALGraph;
//建立邻接表
void CrateGraph(ALGraph *G)
{
int i, k;
int v1, v2; //输入的两个边
int weight; //权值
printf_s("请输入邻接表的总顶点数和边数:");
scanf_s("%d %d", &G->n, &G->e);
fflush(stdin);
printf_s("请输入顶点(回车结束一个输入)\n");
for (i = 0; i < G->n; i++)
{
gets_s(G->adjlist[i].data, MaxVertices);
G->adjlist[i].firstarc = NULL; //初始化边头没有连接的边表
}
printf_s("请根据顶点的位置从1开始输入两两相邻的边和权值(中间用空格隔开)\n");
for (k = 0; k < G->e; k++)
{
fflush(stdin);
printf_s("第%d个连接点:", k + 1);
scanf_s("%d %d %d", &v1, &v2, &weight); //输入相邻的边和权值
v1--; v2--; //按顶点排序从1开始,减去1方便数组计算
ArcNode *s = (ArcNode *)malloc(sizeof(ArcNode));
s->info = weight;
s->adjvex = v2;
s->nextarc = G->adjlist[v1].firstarc;
G->adjlist[v1].firstarc = s;
s = (ArcNode *)malloc(sizeof(ArcNode));//加上后为无向输入
s->adjvex = v1;
s->info = weight;
s->nextarc = G->adjlist[v2].firstarc;
G->adjlist[v2].firstarc = s;
/*s->nextarc = NULL; //尾插法
ArcNode *p;
p = G->adjlist[v1].firstarc;
if (p == NULL)
{
G->adjlist[v1].firstarc = s;
}
else
{
while (p->nextarc)
{
p = p->nextarc;
}
p->nextarc = s;
}*/
}
}
//打印邻接表
void DisGraph(ALGraph *G)
{
int i;
printf_s("序号\t顶点名称\t\t边表\n");
for (i = 0; i < G->n; i++)
{
printf_s("%d\t", i + 1); //打印序号
printf_s("%s\t\t->", G->adjlist[i].data); //打印顶点
while (G->adjlist[i].firstarc)
{
printf_s("%d(%d)->", G->adjlist[i].firstarc->adjvex + 1, G->adjlist[i].firstarc->info);
G->adjlist[i].firstarc = G->adjlist[i].firstarc->nextarc;
}
printf_s("NULL\n");
}
}
//广度优先遍历
int visited[MaxVertices];
typedef struct LoopQueue
{
int data[MaxVertices];
int front;
int rear;
}Queue, *LQueue;
void InitQueue(LQueue Q){ //初始化队列
Q->front = Q->rear = 0;
}
int QueueisFull(LQueue Q){ //判断队列是否满了
if ((Q->rear + 1) % MaxVertices == Q->front){
return -1; //已满
}
else{
return 1;
}
}
int QueueisEmpty(LQueue Q){//判断队列是否为空
if (Q->front == Q->rear){
return -1;
}
return 1;
}
void EnQueue(LQueue Q, int i){ //入队列
if (!QueueisFull(Q)){
Q->data[Q->rear] = i;
Q->rear = (Q->rear + 1) % MaxVertices; //队尾指针后移
}
}
void DeQueue(LQueue Q, int *k){ //出队列
if (!QueueisEmpty(Q)){
*k = Q->data[Q->front];
Q->front = (Q->front + 1) % MaxVertices;
}
}
void BFS(ALGraph *G)
{
Queue Q;
for (int i = 0; i < G->n; i++)
{
visited[i] = 0;
}
InitQueue(&Q); //初始化队列
for (int i = 0; i < G->n; i++)
{
visited[i] = 1;
printf("%s ", G->adjlist[i].data);
EnQueue(&Q, i);
while (!QueueisEmpty(&Q))
{
DeQueue(&Q, &i); //这里不断的修改i的值!!
ArcNode *e = G->adjlist[i].firstarc; //i顶点的邻接链表的第一个结点
while (e)
{ //e存在时,将e的所有邻接点加入队列,也就是遍历i的所有邻接点
if (!visited[e->adjvex])
{ // adjvex是e所表示的结点下标
visited[e->adjvex] = 1;
printf("\t%s", G->adjlist[e->adjvex].data);
EnQueue(&Q, e->adjvex); //将该结点入队
}
e = e->nextarc; //遍历i的下一个邻接点
}
printf_s("\n");
}
}
}
//深度优先遍历
int visited1[MaxVertices];
void DFS(ALGraph *G, int i)
{
ArcNode *p;
visited1[i] = 1;
printf_s("%s ", G->adjlist[i].data);
p = G->adjlist[i].firstarc;
while (p)
{
if (!visited1[p->adjvex])
{
DFS(G, p->adjvex);
}
p = p->nextarc;
}
}
void DFSTravel(ALGraph *G)
{
int i;
for (i = 0; i < G->n; i++)
{
visited1[i] = 0;
}
for (i = 0; i < G->n; i++)
{
if (!visited1[i])
{
DFS(G, i);
}
}
}
void main()
{
ALGraph G;
CrateGraph(&G);
printf_s("\n");
printf_s("广度优先遍历:");
BFS(&G);
printf_s("\n\n");
printf_s("深度优先遍历:");
DFSTravel(&G);
printf_s("\n\n邻接表:\n");
DisGraph(&G);
}
C语言邻接表——广度优先遍历,深度优先遍历
最新推荐文章于 2024-05-21 21:41:01 发布