数据结构 图 C语言
- 进行图的创建(邻接表、邻接矩阵两种方式)
- 进行图的广度优先遍历
- 进行图的深度优先遍历
存储结构:(完整源码)
//邻接表 遍历
//author: 小柳学渣
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define OK 1
#define ERROR 0
#define OVERFLOW 0
typedef int Status;
#define MAX_NAME 3
typedef int InfoType;
typedef char VertexType[MAX_NAME];
#define MAX_VERTEX_NUM 20
//author: 小柳学渣
typedef enum{DG,DN,AG,AN}GraphKind;
typedef struct ArcNode
{
int adjvex;
struct ArcNode *nextarc;
InfoType *info;
}ArcNode;
typedef struct
{
VertexType data;
ArcNode *firstarc;
}VNode, AdjList[MAX_VERTEX_NUM];
typedef struct
{
AdjList vertices;
int vexnum, arcnum;
int kind;
}ALGraph;
//author: 小柳学渣
int LocateVex(ALGraph G, VertexType u)
{
int i;
for (i = 0; i < G.vexnum; ++i)
{
if (strcmp(u, G.vertices[i].data) == 0)
{
return i;
}
}
return -1;
}
Status CreateGraph(ALGraph *G)
{
int i, j, k;
int w;
VertexType va, vb;
ArcNode *p;
printf("0、有向图\n");
printf("1、有向网\n");
printf("2、无向图\n");
printf("3、无向网\n");
printf("请输入图的类型:");
scanf("%d", &(*G).kind);
printf("请输入图的顶点数: ");
scanf("%d", &(*G).vexnum);
printf("请输入图的边数: ");
scanf("%d", &(*G).arcnum);
printf("请输入%d个顶点的值(<%d个字符):\n", (*G).vexnum, MAX_NAME);
for (i = 0; i < (*G).vexnum; ++i)
{
scanf("%s", (*G).vertices[i].data);
(*G).vertices[i].firstarc = NULL;
}
if ((*G).kind == 1 || (*G).kind == 3)
printf("请顺序输入每条弧(边)的权值、弧尾和弧头:\n");
else
printf("请顺序输入每条弧(边)的弧尾和弧头:\n");
for (k = 0; k < (*G).arcnum; ++k)
{
if ((*G).kind == 1 || (*G).kind == 3)
{
printf("权值:");
scanf("%d", &w);
printf("弧尾:");
scanf("%s", va);
printf("弧头:");
scanf("%s", vb);
}
else
{
printf("弧尾:");
scanf("%s", va);
printf("弧头:");
scanf("%s", vb);
}
i = LocateVex(*G, va);
j = LocateVex(*G, vb);
p = (ArcNode*)malloc(sizeof(ArcNode));
p->adjvex = j;
if ((*G).kind == 1 || (*G).kind == 3)
{
p->info = (int *)malloc(sizeof(int));
*(p->info) = w;
}
else
{
p->info = NULL;
}
p->nextarc = (*G).vertices[i].firstarc;
(*G).vertices[i].firstarc = p;
if ((*G).kind >= 2)
{
p = (ArcNode*)malloc(sizeof(ArcNode));
p->adjvex = i;
if ((*G).kind == 3)
{
p->info = (int*)malloc(sizeof(int));
*(p->info) = w;
}
else
{
p->info = NULL;
}
p->nextarc = (*G).vertices[j].firstarc;
(*G).vertices[j].firstarc = p;
}
}
return OK;
}
VertexType* GetVex(ALGraph G, int v)
{
if (v >= G.vexnum || v < 0)
exit(ERROR);
return &G.vertices[v].data;
}
int FirstAdjVex(ALGraph G, VertexType v)
{
ArcNode *p;
int v1;
v1 = LocateVex(G, v);
p = G.vertices[v1].firstarc;
if (p)
return p->adjvex;
else
return -1;
}
int NextAdjVex(ALGraph G, VertexType v, VertexType w)
{
ArcNode *p;
int v1, w1;
v1 = LocateVex(G, v);
w1 = LocateVex(G, w);
p = G.vertices[v1].firstarc;
while (p&&p->adjvex != w1)
p = p->nextarc;
if (!p || !p->nextarc)
return -1;
else
return p->nextarc->adjvex;
}
//author: 小柳学渣
bool visited[MAX_VERTEX_NUM];
void(*VisitFunc)(char* v);
void DFS(ALGraph G, int v)
{
int w;
VertexType v1, w1;
strcpy(v1, *GetVex(G, v));
visited[v] = true;
VisitFunc(G.vertices[v].data);
for (w = FirstAdjVex(G, v1); w >= 0; w = NextAdjVex(G, v1, strcpy(w1, *GetVex(G, w))))
if (!visited[w])
DFS(G, w);
}
/*深度优先搜索*/
void DFSTraverse(ALGraph G, void(*Visit)(char*))
{
int v;
VisitFunc = Visit;
for (v = 0; v < G.vexnum; v++)
visited[v] = false;
for (v = 0; v < G.vexnum; v++)
if (!visited[v])
DFS(G, v);
printf("\n");
}
/*队列的基本操作*/
typedef int QElemType;
typedef struct QNode
{
QElemType data;
struct QNode *next;
}QNode,*QueuePtr;
//author: 小柳学渣
typedef struct
{
QueuePtr front;
QueuePtr rear;
}LinkQueue;
//author: 小柳学渣
/*构造队列*/
Status InitQueue(LinkQueue &Q)
{
Q.front = Q.rear = (QueuePtr)malloc(sizeof(QNode));
if (!Q.front)
{
printf("存储分配失败");
system("pause");
exit(OVERFLOW);
}
Q.front->next = NULL;
return OK;
}
/*销毁队列*/
Status DestroyQueue(LinkQueue &Q)
{
while (Q.front)
{
Q.rear = Q.front->next;
free(Q.front);
Q.front = Q.rear;
}
return OK;
}
/*插入元素到队尾*/
Status EnQueue(LinkQueue &Q, QElemType e)
{
QueuePtr p;
p = (QueuePtr)malloc(sizeof(QNode));
if (!p)
{
printf("存储分配失败");
system("pause");
exit(OVERFLOW);
}
p->data = e;
p->next = NULL;
Q.rear->next = p;
Q.rear = p;
return OK;
}
/*删除队首元素*/
Status DeQueue(LinkQueue &Q, QElemType &e)
{
QueuePtr p;
if (Q.front == Q.rear)
{
printf("队列为空");
return ERROR;
}
p = Q.front->next;
e = p->data;
Q.front->next = p->next;
if (Q.rear == p)
Q.rear = Q.front;
free(p);
return OK;
}
/*判断队列是否为空*/
Status QueueEmpty(LinkQueue &Q)
{
if (Q.front == Q.rear)
return 1;
else
return 0;
}
//author: 小柳学渣
/*广度优先搜索*/
void BFSTraverse(ALGraph G, void(*Visit)(char*))
{
int v, u, w;
VertexType u1, w1;
LinkQueue Q;
for (v = 0; v < G.vexnum; ++v)
visited[v] = false;
InitQueue(Q);
for (v = 0; v < G.vexnum; v++)
if (!visited[v])
{
visited[v] = true;
Visit(G.vertices[v].data);
EnQueue(Q, v);
while (!QueueEmpty(Q))
{
DeQueue(Q, u);
strcpy(u1, *GetVex(G, u));
for (w = FirstAdjVex(G, u1); w >= 0; w = NextAdjVex(G, u1, strcpy(w1, *GetVex(G, w))))
if (!visited[w])
{
visited[w] = true;
Visit(G.vertices[w].data);
EnQueue(Q, w);
}
}
}
printf("\n");
}
void Visit(char *i)
{
printf("%s",i);
}
//author: 小柳学渣
int main()
{
ALGraph G;
CreateGraph(&G);
printf("1、深度优先搜索\n");
printf("2、广度优先搜索\n");
printf("请选择:");
int choice;
scanf("%d",&choice);
switch(choice)
{
case 1:
printf("深度优先搜索:");
DFSTraverse(G, Visit);
break;
case 2:
printf("广度优先搜索:");
BFSTraverse(G, Visit);
break;
}
return 0;
}