数据结构—无向图创建邻接矩阵、深度优先遍历和广度优先遍历(C语言版)

本文介绍了无向图的概念,详细讲解了如何使用C语言创建邻接矩阵,并探讨了深度优先遍历和广度优先遍历的原理。通过实例展示这两种遍历方法,提供完整代码,帮助理解数据结构中的图论算法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、概念解析:

(1)无向图:

假设图G由两个集合V和E组成,记为G={V , E}。其中V是顶点的有限集合,E是连接V中两个不同顶点的边的有限集合。如果E中的顶点对是有序的,即E中的每条边都是有方向的,则称G是有向图。如果顶点对是无序的,则称G是无向图

在这里插入图片描述

在这里插入图片描述

(2)邻接矩阵:

邻接矩阵主要由:二维数组 实现

如图
在这里插入图片描述

转换成邻接矩阵为:

在这里插入图片描述

二、创建邻接矩阵:

基本每一步都有注释,详细观看,建议画图理解

代码如下:

#define MAXSIZE 100 
//	邻接矩阵 
typedef struct Matrix{
   
   
	
	int V_Data;		//	顶点数据域 
	int E_Data;		//	边数数据域
	
	int Node[MAXSIZE];	//	存放顶点数据,也就是顶点表 
	int Weight[MAXSIZE][MAXSIZE]; 	//	存放权重,为矩阵中两点有边的标记符号 
	
}MaTrix,*MATRIX;

//	邻接矩阵数据结构体 
typedef struct Edge{
   
   
	
	int v1;		//	用来存放第一个顶点 
	int v2;		//	用来存放第二个顶点
	int weight;	//	用来存放两点之间的标记符,即为权 
}*EDGE;


//******************** 邻接矩阵*******************//
//	邻接矩阵、顶点和边初始化 
void Init_Matrix(MATRIX S,int Vertex)
{
   
   	
	S->E_Data = 0;			//	初始化为0条边 
	S->V_Data = Vertex;		//	初始化顶点数 
	
	int i,j;
	for(i=0;i<Vertex;i++)
	{
   
   
		for(j=0;j<Vertex;j++)
		{
   
   
			S->Weight[i][j] = 0;
		}
	} 
}

//	开始插入边的权重,即为两个顶点之间边的标记符
void InSerData(MATRIX S,EDGE E)
{
   
   
	//	将输入的顶点v1、v2之间的边,用权作为标记,在矩阵中表示
	//	这里是无向图,所以边没有方向,需要做标记两次(为v1-v2和v2-v1) 
	S->Weight[E->v1][E->v2] = E->weight;	 
	S->Weight[E->v2][E->v1] = E->weight; 
} 

//	开始插入数据 
void InSerEdge_Data(MATRIX S,int edge,int V)
{
   
   
	int i,j;
	
	if(edge>0)	//	边数大于0的时候才插入数据 
	{
   
   
		printf("请输入顶点和权重(空格分隔!)\n");
		for(i=0;i<edge;i++)
		{
   
   		
			EDGE E;				//分配内存,接受顶点v1,v2和权重(标记符)	
			E = (EDGE)malloc(sizeof(struct Edge));	
			
			scanf("%d %d %d",&(E->v1),&(E->v2),&(E->weight));
			
			if(E->v1 ==E->v2)
			{
   
   
				printf("无向图邻接矩阵对角线为0,输入错误,结束运行\n");
				exit(-1); 
			}
			
			InSerData(S,E);
		}	
		printf("请输入要定义的顶点,填入顶点表中: \n");
		for(j=0;j<V;j++)
		{
   
   
			scanf("%d",&(S->Node[j]));
		}
		
	
	}else{
   
   	
		printf("输入的边数错误"); 
	} 
		
} 

三、深度遍历、广度遍历

(1)深度遍历概念:

在这里插入图片描述

在这里插入图片描述

定义的结构体、数组可看上面代码

深度遍历代码解析:

//*****************	深度优先遍历算法—邻接矩阵 *****************//
void DFS_Begin(MATRIX P,int k,int V)
{
   
   
	int i;
	flag[k] = 1;	//标记当前顶点,表示已经遍历过

	printf("%d ",P->Node[k]);	//	输出当前顶点 
	
	for(i=0</
当然可以,以下是使用C语言实现无向图邻接矩阵表示,以及深度优先遍历(使用栈)广度优先遍历(使用队列)的代码。 ```c #include <stdio.h> #include <stdlib.h> #define MAX_VERTICES 100 int visited[MAX_VERTICES]; // 栈的实现 typedef struct { int items[MAX_VERTICES]; int top; } Stack; void initStack(Stack *s) { s->top = -1; } int isEmpty(Stack *s) { return s->top == -1; } void push(Stack *s, int item) { s->items[++(s->top)] = item; } int pop(Stack *s) { return s->items[(s->top)--]; } // 队列的实现 typedef struct { int items[MAX_VERTICES]; int front; int rear; } Queue; void initQueue(Queue *q) { q->front = -1; q->rear = -1; } int isQueueEmpty(Queue *q) { return q->rear == -1; } void enqueue(Queue *q, int item) { if (isQueueEmpty(q)) { q->front = 0; q->rear = 0; } else { q->rear++; } q->items[q->rear] = item; } int dequeue(Queue *q) { int item = q->items[q->front]; if (q->front == q->rear) { q->front = -1; q->rear = -1; } else { q->front++; } return item; } // 图的邻接矩阵表示 typedef struct { int n; // 顶点数 int adjMatrix[MAX_VERTICES][MAX_VERTICES]; } Graph; // 初始化图 void initGraph(Graph *g, int n) { g->n = n; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { g->adjMatrix[i][j] = 0; } } } // 添加边 void addEdge(Graph *g, int u, int v) { g->adjMatrix[u][v] = 1; g->adjMatrix[v][u] = 1; } // 深度优先遍历 void DFS(Graph *g, int v) { Stack s; initStack(&s); push(&s, v); visited[v] = 1; printf("%d ", v); while (!isEmpty(&s)) { int u = pop(&s); for (int i = 0; i < g->n; i++) { if (g->adjMatrix[u][i] && !visited[i]) { push(&s, u); push(&s, i); visited[i] = 1; printf("%d ", i); break; } } } } // 广度优先遍历 void BFS(Graph *g, int v) { Queue q; initQueue(&q); enqueue(&q, v); visited[v] = 1; printf("%d ", v); while (!isQueueEmpty(&q)) { int u = dequeue(&q); for (int i = 0; i < g->n; i++) { if (g->adjMatrix[u][i] && !visited[i]) { enqueue(&q, i); visited[i] = 1; printf("%d ", i); } } } } int main() { Graph g; int n = 5; initGraph(&g, n); addEdge(&g, 0, 1); addEdge(&g, 0, 2); addEdge(&g, 1, 2); addEdge(&g, 1, 3); addEdge(&g, 2, 4); printf("深度优先遍历结果: "); DFS(&g, 0); printf("\n"); for (int i = 0; i < n; i++) { visited[i] = 0; } printf("广度优先遍历结果: "); BFS(&g, 0); printf("\n"); return 0; } ```
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值