数据结构 图 C语言

  1. 进行图的创建(邻接表、邻接矩阵两种方式)
  2. 进行图的广度优先遍历
  3. 进行图的深度优先遍历

在这里插入图片描述
存储结构:(完整源码)

//邻接表  遍历
//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;
}

猜你喜欢

转载自blog.csdn.net/l503301397/article/details/86678203