数据结构——c语言 邻接表

戳这里还有其他数据结构的题目噢

https://blog.csdn.net/qq_45724947/article/details/115625130?spm=1001.2014.3001.5501


设计并验证如下算法:带权图采用邻接表表示,实现无向图的广度优先搜索与有向图的深度优先搜索。

直接上代码

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#define MAXVERTICES 100 //数组大小
int visited[MAXVERTICES]; //访问标志数组
typedef int	QElemType; //队列数据类型
typedef int ElemType;//顶点数据类型

//边表
typedef struct NODE
{
	int adjvex;//顶点下标
	int weight;//权值,只有网(加权图)有
	struct NODE *next;//指向下一个结点
}EdgeNode;

//顶点表
typedef struct
{
	ElemType vertex;//顶点的值
	EdgeNode *edgenext;//边表
}VertexNode;

typedef VertexNode AdjList[MAXVERTICES];
//图
typedef struct
{
	AdjList adjlist;
	int Vn;//顶点个数
	int Ve;//边的个数
}AdjTable;



//创建邻接表
void creatTable1(AdjTable *G)
{
	int n, e, vi, vj, w;
	EdgeNode *s;
	printf("请输入有向图图的顶点和边的个数(用空格隔开):");
	scanf("%d%d", &n, &e);
	G->Vn = n;
	G->Ve = e;
	//建立顶点表
	printf("\n建立顶点表");
	for (int i = 0; i < G->Vn; i++)
	{
		printf("\n请输入第%d个顶点的信息:", i + 1);
		scanf("%d", &G->adjlist[i].vertex);
		G->adjlist[i].edgenext = NULL;
	}
	//建立边表-前插法
	printf("\n建立边表\n");
	for (int j = 0; j < G->Ve; j++)
	{
		printf("输入有链接的顶点下标和权值(用空格隔开):\n");//无权图权值为1
		scanf("%d%d%d", &vi, &vj, &w);
		vi -= 1;
		vj -= 1;
		
		s = (EdgeNode*)malloc(sizeof(EdgeNode));
		s->adjvex = vj;
		s->weight = w;
		s->next = G->adjlist[vi].edgenext;
		G->adjlist[vi].edgenext = s;
	}
}
void creatTable2(AdjTable *G)
{
	int n, e, vi, vj, w;
	EdgeNode *s;
	printf("请输入无向图图的顶点和边的个数(用空格隔开):");
	scanf("%d%d", &n, &e);
	G->Vn = n;
	G->Ve = e;
	//建立顶点表
	printf("\n建立顶点表");
	for (int i = 0; i < G->Vn; i++)
	{
		printf("\n请输入第%d个顶点的信息:", i + 1);
		scanf("%d", &G->adjlist[i].vertex);
		G->adjlist[i].edgenext = NULL;
	}
	//建立边表-前插法
	printf("\n建立边表\n");
	for (int j = 0; j < G->Ve; j++)
	{
		printf("输入有链接的顶点下标和权值(用空格隔开):\n");//无权图权值为1
		scanf("%d%d%d", &vi, &vj, &w);
		vi -= 1;
		vj -= 1;
		s = (EdgeNode*)malloc(sizeof(EdgeNode));
		s->adjvex = vj;
		s->weight = w;
		s->next = G->adjlist[vi].edgenext;
		G->adjlist[vi].edgenext = s;

		s = (EdgeNode*)malloc(sizeof(EdgeNode));
		s->adjvex = vi;
		s->weight = w;
		s->next = G->adjlist[vj].edgenext;
		G->adjlist[vj].edgenext = s;	
			
	}
}
//显示连接表
void ShowAdjTable(AdjTable *G)
{
	printf("显示顶点信息:\n");
	for (int i = 0; i < G->Vn; i++)
	{
		printf("%d ", G->adjlist[i].vertex);
	}
	printf("\n显示边的信息:\n");
	for (int i = 0; i < G->Vn; i++)
	{
		EdgeNode *q = G->adjlist[i].edgenext;
		printf("%d->", i + 1);
		while (1)
		{
			if (q == NULL)
			{
				printf("^");
				break;
			}
			printf("(w = %d)->%d    ->", q->weight, q->adjvex + 1);
			q = q->next;
		}
		printf("\n");
	}
}

//邻接表的深度优先搜索
void DFS(AdjTable *G, int i)
{
	EdgeNode *p;
	visited[i] = 1;
	printf("%d->", G->adjlist[i].vertex);
	p = G->adjlist[i].edgenext;//让p指向边表的第一个结点
	while (p)
	{
		if (!visited[p->adjvex])
		{
			DFS(G, p->adjvex);
		}
		p = p->next;
	}

}
void DFSTraverse(AdjTable *G)
{
	for (int i = 0; i < G->Vn; i++)
	{
		visited[i] = 0;//初始化标记数组为0
	}
	for (int i = 0; i < G->Vn; i++)
	{
		if (!visited[i])
		{
			DFS(G, i);
		}
	}
}
//邻接表的广度优先搜索

//队列结构
typedef struct Qnode
{
	QElemType data;
	struct Qnode *next;
}Qnode, *Qptr;     //定义节点

typedef struct LINKQUEUE
{
	Qptr front;
	Qptr rear;
}LinkQueue;       //定义队首、队尾指针

void InitQueue(LinkQueue *q) //队列初始化
{
	//定义头结点,队首队尾都指向头结点
	Qptr firstnode = (Qptr)malloc(sizeof(Qnode));
	q->front = q->rear = firstnode;
	if (!q->front)
	{
		exit(0);
	}
	q->front->next = NULL;
}
//入队列
void PushQueue(LinkQueue *q, QElemType e)
{
	//在队尾插入元素
	Qptr p = (Qptr)malloc(sizeof(Qnode));
	if (!p)
	{
		exit(0);
	}
	p->data = e;
	p->next = NULL;
	q->rear->next = p;
	q->rear = p;
}
//出队列
void DetQueue(LinkQueue *q, QElemType &e)
{
	//出队列在队首进行
	if (q->front == q->rear)
	{
		printf("队列中无元素!\n");
		exit(0);
	}
	Qptr p = q->front->next;
	e = p->data;
	q->front->next = p->next;
	if (q->rear == p)
	{
		q->rear = q->front;
	}
	free(p);
}
//检验是否为空
int QueueEmpty(LinkQueue *q)
{
	if (q->front == q->rear)
		return 0;
	else
		return 1;
}
//广度优先遍历
void BFSTraverse(AdjTable *G)
{
	int k;
	LinkQueue Q;
	EdgeNode *e;
	InitQueue(&Q);
	for (int i = 0; i < G->Vn; i++)
	{
		visited[i] = 0;//初始化标记数组
	}
	for (int i = 0; i < G->Vn; i++)
	{
		if (!visited[i])
		{
			visited[i] = 1;
			printf("%d->", G->adjlist[i].vertex);
			PushQueue(&Q, i);
		}
		while (QueueEmpty(&Q))
		{
			DetQueue(&Q, k);
			e = G->adjlist[k].edgenext;
			while (e)
			{
				if (!visited[e->adjvex])
				{
					visited[e->adjvex] = 1;
					printf("%d->", G->adjlist[e->adjvex].vertex);
					PushQueue(&Q, e->adjvex);
				}
				e = e->next;
			}
		}
	}
}
int main()
{
	AdjTable G1,G2;
	creatTable1(&G1);
	ShowAdjTable(&G1);
	printf("\n深度优先遍历:\n");
	DFSTraverse(&G1);
	printf("\n\n");
	
	creatTable2(&G2);
	ShowAdjTable(&G2);
	printf("\n广度优先遍历:\n");
	BFSTraverse(&G2);
	printf("\n\n");
	

	system("pause");
	return 0;
}

 (代码如有雷同,可能存在借鉴他人部分代码情况)

(请不要直接复制使用。总结的代码仅供参考,希望读者借此代码自身可以理解学习)

如果代码对您有帮助,不要忘记评论收藏噢~

  • 7
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

起当风萧

如果喜欢请支持一下~~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值