以邻接表方式建立有向图,分别利用深度优先遍历和广度优先遍历方法输出各结点元素(数据结构)

实验目的

  1. 掌握图的邻接矩阵和邻接表存储结构;
  2. 掌握图的深度优先遍历和广度优先遍历算法,复习栈和队列的应用;
  3. 掌握图的最小生成树、拓扑排序等应用及算法思想。

实验内容

以邻接矩阵或邻接表方式建立有向图,并分别利用深度优先遍历和广度优先遍历方法输出各结点元素。

下面代码是用邻接表建立的有向图

Source Code

#include<stdio.h>
#include<malloc.h>
#define MAXV 100				//顶点数目的最大值 

int visited[MAXV];				//深度访问标记数组 
int BFSvisited[MAXV];			//广度访问标记数组 

typedef struct ANode
{	
	int adjNode;	//该边的邻接点编号
	ANode *next;	//指向下一条边的指针
}ArcNode;	//边结点类型

typedef struct Vnode
{
	char data;		//顶点信息
	ArcNode *first;	//指向第一个边结点
}VNode,AdjList[MAXV];	//头结点类型
 
typedef struct
{
	AdjList vertices;
	int n,e;//顶点数n和边数e
}ALGraph;	//图邻接表类型
 
//创建有向图 
void CreateGraph(ALGraph &g){
	printf("请输入顶点数和边数:");
	int n,e;
	scanf("%d%d",&n,&e);
	g.n=n;
	g.e=e;
	for(int i=0;i<g.n;i++){
		g.vertices[i].data=i;
		g.vertices[i].first=NULL; 
	}
	printf("请输入每条边的两个顶点(用空格隔开)\n");
	int x,y;
	for(i=0;i<g.e;i++){
		scanf("%d%d",&x,&y);
		ArcNode *p =(ArcNode*)malloc(sizeof(ArcNode));
		p->adjNode=y;
		p->next=g.vertices[x].first;
		g.vertices[x].first=p;
		ArcNode *q=(ArcNode*)malloc(sizeof(ArcNode));
		q->adjNode=x;
		q->next=g.vertices[y].first;
		g.vertices[y].first=q;
	
	}
} 
 
//深度优先遍历图,从第v个顶点开始遍历 
void DFS(ALGraph g,int v)
{
	visited[v]=true;
	printf("%d  ",g.vertices[v].data); 
	ArcNode *p=g.vertices[v].first;
	int w;
	while(p!=NULL){
		w=p->adjNode;
		if(!visited[w]){
			DFS(g,w);		//递归深度遍历 
		}
		p=p->next;
	}
} 

//广度优先遍历借助队列,从v开始遍历 
void BFS(ALGraph g,int v)
{
	BFSvisited[v]=true;
	ArcNode *p;
	printf("%d  ",g.vertices[v].data);
	int que[MAXV];
	int front=0,rear=0;
	rear=(rear+1)%MAXV;
	que[rear]= v;
	int j;
	while(rear!=front)	//当队列不空的时候
	{						 
		front=(front+1)%MAXV;//出队 
		j =que[front];
		p =g.vertices[j].first;
		while(p!=NULL)
		{
			if(!BFSvisited[p->adjNode])
			{
				printf("%d  ",g.vertices[p->adjNode].data);
				BFSvisited[p->adjNode]=true;
				rear=(rear+1)%MAXV;
				que[rear]=p->adjNode; 
			}
			p=p->next;//用的是邻接表,用p-next就可访问同层的相邻结点 
			
		}	
	}
}

int main()
{
	ALGraph g;
	CreateGraph(g);
	printf("深度优先遍历顺序:\n"); 
	DFS(g,0); 
	printf("\n");
	printf("广度优先遍历顺序:\n"); 
	BFS(g,0);
	printf("\n");
} 

Computational Results

在这里插入图片描述

Hint

此代码遍历过程是从初始点0开始遍历的,对应的图是
在这里插入图片描述

  • 9
    点赞
  • 69
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,我可以回答你的问题。以下是用C语言以邻接表方式建立有向图,分别利用深度优先遍历广度优先遍历方法输出结点元素的代码: ```c #include <stdio.h> #include <stdlib.h> #define MAXV 100 // 最大顶点数 typedef struct node { int v; // 邻接点编号 struct node *next; // 指向下一个邻接点的指针 } Node; typedef struct graph { Node *adj[MAXV]; // 邻接表 int n; // 顶点数 } Graph; int visited[MAXV]; // 记录节点是否已被访问 // 创建邻接表 void createGraph(Graph *G, int n) { int i, u, v; Node *p; G->n = n; for (i = 0; i < n; i++) { G->adj[i] = NULL; } printf("请输入边的起点和终点,以-1结束:\n"); while (scanf("%d%d", &u, &v) == 2 && u != -1 && v != -1) { p = (Node *)malloc(sizeof(Node)); p->v = v; p->next = G->adj[u]; G->adj[u] = p; } } // 深度优先遍历 void DFS(Graph *G, int v) { Node *p; visited[v] = 1; printf("%d ", v); for (p = G->adj[v]; p != NULL; p = p->next) { if (!visited[p->v]) { DFS(G, p->v); } } } // 广度优先遍历 void BFS(Graph *G, int v) { int queue[MAXV]; int front = 0, rear = 0; Node *p; visited[v] = 1; printf("%d ", v); queue[rear++] = v; while (front < rear) { v = queue[front++]; for (p = G->adj[v]; p != NULL; p = p->next) { if (!visited[p->v]) { visited[p->v] = 1; printf("%d ", p->v); queue[rear++] = p->v; } } } } int main() { Graph G; int n, v; printf("请输入顶点数:"); scanf("%d", &n); createGraph(&G, n); // 深度优先遍历 printf("深度优先遍历结果:"); for (v = 0; v < G.n; v++) { visited[v] = 0; } for (v = 0; v < G.n; v++) { if (!visited[v]) { DFS(&G, v); } } printf("\n"); // 广度优先遍历 printf("广度优先遍历结果:"); for (v = 0; v < G.n; v++) { visited[v] = 0; } for (v = 0; v < G.n; v++) { if (!visited[v]) { BFS(&G, v); } } printf("\n"); return 0; } ``` 以上代码中,`Graph` 结构体表示图,包括邻接表和顶点数;`Node` 结构体表示邻接表中的一个结点,包括邻接点编号和指向下一个邻接点的指针;`visited` 数组记录节点是否已被访问;`createGraph` 函数用于创建图;`DFS` 函数用于深度优先遍历;`BFS` 函数用于广度优先遍历。 在 `main` 函数中,首先创建了一个图 `G`,然后对其进行深度优先遍历广度优先遍历。注意,在遍历之前需要将 `visited` 数组初始化为零,以确保每个节点都能被遍历到。遍历的顺序是从顶点0开始依次遍历,如果还有没有被遍历的节点,则从该节点开始继续遍历。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值