详解邻接矩阵和邻接表分别实现DFS和BFS——C++

题目:

采用邻接矩阵和邻接表存储结构来建立有向图或无向图,实现深度优先或广度优先的遍历算法。

测试图:

在这里插入图片描述

代码1:

/*采用邻接矩阵存储图*/ 
#include<iostream>
#include<cstring>
#include<queue> 
#include<map> 
using namespace std;

const int INF=0x3f3f3f3f;
const int MVNum=100;			//最大顶点数 
int visited[MVNum];				//访问数组 
map<char ,int> mp;
	
typedef struct{					//邻接矩阵存储无向图 
	char vexs[MVNum];			//假设顶点数据类型为字符型 
	int arcs[MVNum][MVNum];		//假设边的权值类型为整形
	int vexnum,arcnum;			//图的点数和边数 
}Graph;

void CreateGraph(Graph &G){
	int w;
	char v1,v2;
	cout<<"输入图的顶点数和边数:"<<endl; 
	cin>>G.vexnum>>G.arcnum;
	cout<<"依次输入"<<G.vexnum<<"个顶点:"<<endl; 
	for(int i=0;i<G.vexnum;++i){
		cin>>G.vexs[i];
		mp[G.vexs[i]]=i;		//顶点在图中的位置即为顶点的输入次序
	}
	memset(G.arcs,INF,sizeof(G.arcs));	//初始化邻接矩阵 
	cout<<"依次输入"<<G.arcnum<<"条边的两个顶点和权值"<<endl; 
	for(int i=0;i<G.arcnum;++i){
		cin>>v1>>v2>>w;
		G.arcs[mp[v1]][mp[v2]]=w;
		G.arcs[mp[v2]][mp[v1]]=w;
	} 
}

void DFS(Graph G,int v){
	cout<<G.vexs[v];
	visited[v]=1;
	for(int w=0;w<G.vexnum;++w){
		if((!visited[w])&&(G.arcs[v][w]!=INF)){
			DFS(G,w);
		}
	}
}

void BFS(Graph G,int v){
	cout<<G.vexs[v];
	visited[v]=1;
	queue<int> Q; 	//STL
	Q.push(v);
	while(!Q.empty()){
		int u=Q.front();
		Q.pop();
		for(int w=0;w<G.vexnum;++w){
			if((!visited[w])&&(G.arcs[u][w]!=INF)){
				cout<<G.vexs[w];
				visited[w]=1;
				Q.push(w);
			}
		}
	} 
	
}

int main(){
	Graph G;
	CreateGraph(G);
	cout<<"DFS:"; 
	DFS(G,0);		//从第0个顶点开始DFS
	memset(visited,0,sizeof(visited));	//重新初始化visited数组
	cout<<endl<<"BFS:"; 
	BFS(G,0);		//从第0个顶点开始BFS 
	return 0;
}

代码1运行结果:

在这里插入图片描述

代码2:

/*采用邻接表存储图*/ 
#include<iostream>
#include<queue> 
#include<map>
#include<cstring>
using namespace std;

const int MVNum=100;		//最大顶点数
map<char,int> mp;			//使用map来存储顶点对应邻接表中的位置 
int visited[MVNum];

typedef struct ArcNode{		//边结点 
	int adjvex;
	struct ArcNode *nextarc; 
}ArcNode;

typedef struct VNode{		//顶点信息 
	char data;
	ArcNode *firstarc;
}VNode,AdjList[MVNum];

typedef struct{				//邻接表 
	AdjList vertices;
	int vexnum,arcnum; 
}Graph;

void CreateGraph(Graph &G){
	char v1,v2;
	cout<<"输入图的顶点数和边数:"<<endl; 
	cin>>G.vexnum>>G.arcnum;
	cout<<"依次输入"<<G.vexnum<<"个顶点:"<<endl; 
	for(int i=0;i<G.vexnum;++i){
		cin>>G.vertices[i].data;
		G.vertices[i].firstarc=NULL;
		mp[G.vertices[i].data]=i;
	}
	cout<<"依次输入"<<G.arcnum<<"条边的两个顶点"<<endl; 
	for(int k=0;k<G.arcnum;++k){
		cin>>v1>>v2;
		int i=mp[v1];
		int j=mp[v2];
		ArcNode *p1=new ArcNode;
		p1->adjvex=j;
		p1->nextarc=G.vertices[i].firstarc;
		G.vertices[i].firstarc=p1;
		ArcNode *p2=new ArcNode;
		p2->adjvex=i;
		p2->nextarc=G.vertices[j].firstarc;
		G.vertices[j].firstarc=p2;
	}
}

void DFS(Graph G,int v){
	cout<<G.vertices[v].data;
	visited[v]=1;
	ArcNode *p=G.vertices[v].firstarc;
	while(p!=NULL){
		int w=p->adjvex;
		if(!visited[w]) DFS(G,w);
		p=p->nextarc;
	}
}

void BFS(Graph G,int v){
	cout<<G.vertices[v].data;
	visited[v]=1;
	queue<int> Q;			//队列 
	Q.push(v);
	while(!Q.empty()){
		int w=Q.front();
		Q.pop();
		ArcNode *p=G.vertices[w].firstarc;
		while(p!=NULL){
			if(!visited[p->adjvex]){
				cout<<G.vertices[p->adjvex].data;
				visited[p->adjvex]=1;
				Q.push(p->adjvex);
			}
			p=p->nextarc;	//注意 
		}
	}
}

int main(){
	Graph G;
	CreateGraph(G);
	cout<<"DFS:"; 
	DFS(G,0);		//从第0个顶点开始DFS
	memset(visited,0,sizeof(visited));	//重新初始化visited数组
	cout<<endl<<"BFS:"; 
	BFS(G,0);		//从第0个顶点开始BFS 
	return 0;
}

代码2运行结果:

在这里插入图片描述

  • 5
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
下面是基于邻接矩阵实现DFSBFS代码: ```c #include <stdio.h> #include <stdlib.h> #include <stdbool.h> #define MAX_VERTEX_NUM 100 typedef struct Graph { int vertex[MAX_VERTEX_NUM]; int matrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; int vertex_num; int edge_num; } Graph; typedef struct Queue { int data[MAX_VERTEX_NUM]; int front, rear; } Queue; // 初始化队列 void InitQueue(Queue* queue) { queue->front = queue->rear = 0; } // 判断队列是否为空 bool IsQueueEmpty(Queue* queue) { return queue->front == queue->rear; } // 入队 bool EnQueue(Queue* queue, int x) { if ((queue->rear + 1) % MAX_VERTEX_NUM == queue->front) { return false; } queue->data[queue->rear] = x; queue->rear = (queue->rear + 1) % MAX_VERTEX_NUM; return true; } // 出队 bool DeQueue(Queue* queue, int* x) { if (IsQueueEmpty(queue)) { return false; } *x = queue->data[queue->front]; queue->front = (queue->front + 1) % MAX_VERTEX_NUM; return true; } // 初始化图 void InitGraph(Graph* graph) { int i, j; printf("输入顶点数和边数:"); scanf("%d%d", &graph->vertex_num, &graph->edge_num); for (i = 0; i < graph->vertex_num; ++i) { printf("输入第%d个顶点的值:", i); scanf("%d", &graph->vertex[i]); } for (i = 0; i < graph->vertex_num; ++i) { for (j = 0; j < graph->vertex_num; ++j) { graph->matrix[i][j] = 0; } } for (i = 0; i < graph->edge_num; ++i) { int v1, v2; printf("输入第%d条边的起点和终点:", i); scanf("%d%d", &v1, &v2); graph->matrix[v1][v2] = 1; graph->matrix[v2][v1] = 1; } } // DFS历 void DFS(Graph* graph, bool* visited, int v) { int i; printf("%d ", graph->vertex[v]); visited[v] = true; for (i = 0; i < graph->vertex_num; ++i) { if (graph->matrix[v][i] == 1 && !visited[i]) { DFS(graph, visited, i); } } } // BFS历 void BFS(Graph* graph, bool* visited, Queue* queue, int v) { int i; printf("%d ", graph->vertex[v]); visited[v] = true; EnQueue(queue, v); while (!IsQueueEmpty(queue)) { int u; DeQueue(queue, &u); for (i = 0; i < graph->vertex_num; ++i) { if (graph->matrix[u][i] == 1 && !visited[i]) { printf("%d ", graph->vertex[i]); visited[i] = true; EnQueue(queue, i); } } } } int main() { Graph graph; bool visited[MAX_VERTEX_NUM]; Queue queue; int i; InitGraph(&graph); for (i = 0; i < graph.vertex_num; ++i) { visited[i] = false; } printf("DFS历结果:"); for (i = 0; i < graph.vertex_num; ++i) { if (!visited[i]) { DFS(&graph, visited, i); } } printf("\n"); for (i = 0; i < graph.vertex_num; ++i) { visited[i] = false; } InitQueue(&queue); printf("BFS历结果:"); for (i = 0; i < graph.vertex_num; ++i) { if (!visited[i]) { BFS(&graph, visited, &queue, i); } } printf("\n"); return 0; } ``` 这里利用邻接矩阵存储图结构,实现DFSBFS历算法。在程序中,首先通过InitGraph函数读入图的顶点数、边数以及每个顶点的值,然后通过邻接矩阵表示图的连通关系。DFSBFS历时,都需要记录每个节点是否已经被访问过,因此定义了visited数组用于记录。DFS采用递归方式,而BFS历则利用队列实现
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

枯木何日可逢春

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值