图的深度优先遍历和广度优先遍历(邻接表存储图 C++实现)

1、问题描述
对给定的下图采用邻接表结构存储,并分别用深度优先和广度优先搜索对图进行遍历。
在这里插入图片描述

#include<iostream>
#include<stdlib.h>
#include<queue>
#define MAXLEN 100
using namespace std;
typedef char DataType;
bool visited[MAXLEN];
typedef struct EdgeNode {   //边结点 
	int adjvex;            //邻接点在顶点数组中的下标 
	struct EdgeNode* next;//链域  指向下一个邻接点 
}EdgeNode;

typedef struct VertexNode {   //头结点 
	DataType data;  //顶点信息
	EdgeNode* link; //边表头指针(指向第一条依附于该顶点的弧的指针) 
}VertexNode;

typedef struct Graph {
	VertexNode adjList[MAXLEN];
	int numVertexes, numEdges;  //图中当前的结点数及边数 
}Graph;
void CreateGraph(Graph* G)   //建立无向图的邻接表 
{


	cout << "输入图的顶点数:" << endl;
	cin >> G->numVertexes;

	cout << "输入图的边数:" << endl;
	cin >> G->numEdges;
	int i, j, k;
	cout << "输入各个顶点的数据:" << endl;
	for (i = 1;i <= G->numVertexes;i++)
	{
		cout << "顶点" << i << ":" << endl;
		cin >> G->adjList[i].data;
		G->adjList[i].link = NULL;
	}

	for (k = 1;k <= G->numEdges;k++)
	{

		cout << "输入(vi,vj)上的顶点序号:" << endl;
		cin >> i >> j;

		EdgeNode* t;
		EdgeNode* p = new EdgeNode;
		if (G->adjList[i].link != NULL)
		{
			t = G->adjList[i].link;
			while (t->next != NULL)
				t = t->next;
				p->adjvex = j; p->next = NULL; t->next = p;
		}
		else
		{
			p->adjvex = j; p->next = G->adjList[i].link; G->adjList[i].link = p;
		}
		p = new EdgeNode;
		if (G->adjList[j].link != NULL)
		{
			t = G->adjList[j].link;
			while (t->next != NULL)
				t = t->next;
			p->adjvex = i;p->next = NULL;t->next = p;
		}
		else
		{
			p->adjvex = i; p->next = G->adjList[j].link; G->adjList[j].link = p;
		}

	}
}
//广度优先遍历算法
void BFSTraverse(Graph* G)
{
	cout << "广度优先遍历的结果为:" << endl;
	queue<int>q;
	int i;
	for (i = 1;i <= G->numVertexes;i++)
		visited[i] = false;

	for (i = 1;i <= G->numVertexes;i++)
	{
		if (!visited[i])
		{
			visited[i] = true;
			cout << G->adjList[i].data;
			q.push(i);

			while (!q.empty())
			{
				EdgeNode* p = G->adjList[q.front()].link;
				q.pop();
				while (p != NULL)
				{
					if (visited[p->adjvex] == false)
					{
						visited[p->adjvex] = true;
						cout << G->adjList[p->adjvex].data;
						q.push(p->adjvex);
					}
					p = p->next;
				}
			}
		}
	}
	cout << endl;
}
//深度优先遍历算法
void DFS(Graph* G, int i)
{
	visited[i] = true;
	cout << G->adjList[i].data;

	EdgeNode* p = G->adjList[i].link;

	while (p)
	{
		if (!visited[p->adjvex])
			DFS(G, p->adjvex);
		p = p->next;
	}
}

void DFSTraverse(Graph* G)
{
	cout << "深度优先遍历的结果为:" << endl;
	int i;
	for (i = 1;i <= G->numVertexes;i++)
		visited[i] = false;       //初始化访问数组visited的元素值为false

	for (i = 1;i <= G->numVertexes;i++)
		if (!visited[i])     //结点尚未访问 
		{
			DFS(G, i);
		}

	cout << endl;
}

void main()
{
	Graph G;
	CreateGraph(&G);
	DFSTraverse(&G);
	BFSTraverse(&G);

}

输出数据:
深度优先序列: 1→2→4→8→5→3→6→7
广度优先序列: 1→2→3→4→5→6→7→8

  • 2
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
好的,这里给出一个简单的邻接表实现广度优先遍历深度优先遍历的示例代码: ```cpp #include <iostream> #include <queue> #include <stack> #include <vector> using namespace std; const int MAXN = 1005; vector<int> G[MAXN]; // 邻接表存储 bool vis[MAXN]; // 记录节点是否被访问过 void bfs(int s) { queue<int> q; q.push(s); vis[s] = true; while (!q.empty()) { int u = q.front(); q.pop(); cout << u << " "; for (int i = 0; i < G[u].size(); ++i) { int v = G[u][i]; if (!vis[v]) { q.push(v); vis[v] = true; } } } } void dfs(int u) { vis[u] = true; cout << u << " "; for (int i = 0; i < G[u].size(); ++i) { int v = G[u][i]; if (!vis[v]) { dfs(v); } } } void init() { for (int i = 0; i < MAXN; ++i) { G[i].clear(); vis[i] = false; } } int main() { int n, m; cin >> n >> m; init(); for (int i = 1; i <= m; ++i) { int u, v; cin >> u >> v; G[u].push_back(v); G[v].push_back(u); } cout << "BFS: "; for (int i = 1; i <= n; ++i) { if (!vis[i]) { bfs(i); } } cout << endl; memset(vis, false, sizeof(vis)); cout << "DFS: "; for (int i = 1; i <= n; ++i) { if (!vis[i]) { dfs(i); } } cout << endl; return 0; } ``` 在上面的代码中,我们使用 `vector` 来存储邻接表,使用 `bool` 类型数组 `vis` 来记录节点是否已经被访问过。广度优先遍历使用了一个队列来实现,而深度优先遍历使用了递归的方式实现。 这里的 `init()` 函数用于初始化邻接表和访问标记等。在主函数中,我们通过输入的节点数 `n` 和边数 `m`,并对每条边建立邻接表,然后使用广度优先遍历深度优先遍历依次遍历整个

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值