实验6.2 无向图的深度和广度遍历

头文件

#include<stdio.h>
#include<stdlib.h>
#define MAX 20

定义结构体

typedef int Vextype;
typedef struct Vnode
{
	Vextype data;
	struct Vnode* next;
}Vnode;
typedef Vnode Lgraph[MAX];
typedef struct
{
	int V[MAX];
	int front;
	int rear;
}Queue;

定义变量

Lgraph Ga;
int n, e, visited[MAX];

创建无向图

void creat_L(Lgraph G)
{
	Vnode* p, * q;
	int i, j, k;
	printf("\n请输入图的顶点数和边数:");
	scanf("%d %d", &n, &e);
	for (i = 1;i <= n;i++)
	{
		G[i].data = i; //G为无权值的无向图,故所有顶点依次编号为1……n
		G[i].next = NULL; //初始化时,顶点结点的后继结点为0
	}
	for (k = 1;k <= e;k++)
	{
		printf("\n请输入每条边的两个顶点编号:");
		scanf("%d %d", &i, &j);
		//将j结点插入到顶点i的临界表中
		p = (Vnode*)malloc(sizeof(Vnode));
		p->data = i;
		p->next = G[j].next;
		G[j].next = p;
		//将结点i插入到顶点j的临界表中
		q = (Vnode*)malloc(sizeof(Vnode));
		q->data = j;
		q->next = G[i].next;
		G[i].next = q;
	}
}

输出无向图

void output_L(Lgraph G)
{
	int i;
	Vnode* p;
	printf("\n无向图的邻接表为:\n");
	for (i = 1;i <= n;i++)
	{
		printf("\n%d->", i); //先输出顶点 
		p = G[i].next;
		while (p != NULL)
		{
			printf("%d->", p->data); //再依次输出顶点之后的链表 
			p = p->next;
		}
	}
}

初始化队列

void initqueue(Queue* q)
{
	q->front = -1;
	q->rear = -1;
}

判断队列是否为空

int quempty(Queue* q)
{
	if (q->front == q->rear)
	{
		return 1;
		//队列为空则返回1
	}
	else
	{
		return 0;
	}
}

入队

void enqueue(Queue* q, int e)
{
	//判断队列是否已满
	if ((q->rear + 1) % MAX == q->front)
		printf("队列满!\n");
	else
	{
		q->rear = (q->rear + 1) % MAX;
		q->V[q->rear] = e;
	}
}

出队

int dequeue(Queue* q)
{
	int t;
	if (q->front == q->rear)
	{
		printf("队列空!\n");
		return 0;
	}
	else
	{
		q->front = (q->front + 1) % MAX;
		t = q->V[q->front];
		return t;
	}
}


深度优先遍历

void dfsl(Lgraph G, int v)
{
	Vnode* p;
	//输出当前结点的值 
	printf("%d->", G[v].data);
	//输出过的visit值设为1,避免重复访问 
	visited[v] = 1;
	//p为连在v顶点之后的链表 
	p = G[v].next;
	while (p != NULL)
	{
		v = p->data;
		if (visited[v] == 0)
		{
			//对未访问过的结点,利用递归算法遍历 
			dfsl(G, v);
		}
		p = p->next;
	}
}

广度优先遍历

void bfsl(Lgraph G, int v)
{
	Vnode* p;
	int x;
	//对队列q初始化 
	Queue* q = (Queue*)malloc(sizeof(Queue));
	initqueue(q);
	//输出当前顶点的值 
	printf("%d->", G[v].data);
	//已访问过的结点的visit值设为1 
	visited[v] = 1;
	//将该顶点入队 
	enqueue(q, v);
	while (!quempty(q))
	{
		//将队列中出队元素的值赋给x 
		x = dequeue(q);
		//p为连在x顶点之后的链表 
		p = G[x].next;
		while (p)
		{
			//将子链中未访问的元素输出并入队,visit值置1 
			//再依次以队列中的元素为顶点,寻找子链中未访问元素并输出 
			v = p->data;
			if (visited[v] == 0)
			{
				printf("%d->", G[v].data);
				visited[v] = 1;
				enqueue(q, v);
			}
			p = p->next;
		}
	}
}

主函数

int main()
{
	int v1, i;//v1表示遍历的开始结点,i用于for循环
	for (i = 1;i < MAX;i++)
	{
		visited[i] = 0;
	}
	creat_L(Ga); //创建无向图
	output_L(Ga); //输出无向图
	printf("\n请输入深度优先遍历的出发点:");
	scanf("%d", &v1);
	printf("\n深度优先遍历的结果为:");
	dfsl(Ga, v1);
	for (i = 1;i < MAX;i++)
	{
		visited[i] = 0;
	}
	printf("\n\n请输入广度优先遍历的出发点:");
	scanf("%d", &v1);
	printf("\n广度优先遍历的结果为:");
	bfsl(Ga, v1);
}

运行结果

在这里插入图片描述

  • 2
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值