枯木逢春不再茂, 年少且惜镜人
无向图的存储以及遍历(邻接表以及DFS BFS)
之前写过邻接矩阵(比较好理解 ,当时queue还是数组写的 比较low 不好容易理解),那今天我来写写较为复杂一点的邻接表
多的不说直接上代码
#include <iostream>
#include <string>
#include <queue>
using namespace std;
typedef char vertexType; //顶点的数据类型,这里姑且设为字符,A,B,C,D
#define MAXVEX 100 //最大顶点数
bool visited[MAXVEX]; //访问标记
struct edgeNode //边节点,最内层
{
int adjvex; //index
struct edgeNode* next; //邻接表的next;
};
typedef struct vertexNode //节点数据
{
vertexType data; //节点数据 用户自己定义
edgeNode* firstEdge; //邻接表 头节点
}AdjList[MAXVEX]; //结构体数组 在AdjListGraph中定义;
struct AdjListGraph //图结构
{
AdjList adjList; //邻接表
int numVertex, numEdge; //顶点数,边数
};
void createMGraph(AdjListGraph* G)
{
edgeNode* e, *f;
cout << "请输入顶点数,边数:";
cin >> G->numVertex >> G->numEdge; //节点数 和边数
cout << "请输入每个顶点的字母表示:";
for (int i = 0; i < G->numVertex; i++)
{
cin >> G->adjList[i].data;
G->adjList[i].firstEdge = nullptr; //nullptr 关键字空指针
}
cout << "请输入每条边的起点序号,终点序号:";
for (int i = 0; i < G->numEdge; i++)//无向图
{
int start, end;
cin >> start >> end;
e = new edgeNode;//类似于一个头差法的构建表
e->adjvex = end;
e->next = G->adjList[start].firstEdge;
G->adjList[start].firstEdge = e;
f = new edgeNode; //因为是无向图 所以a-b有边 b-a也又边
f->adjvex = start;
f->next = G->adjList[end].firstEdge;
G->adjList[end].firstEdge = f;
}
}
void DFS(AdjListGraph G, int i) //深度优先搜索
{
visited[i] = true;
edgeNode* p;
cout << G.adjList[i].data << " ";
p = G.adjList[i].firstEdge;
while (p)
{
if (!visited[p->adjvex])
{
DFS(G, p->adjvex);
}
p = p->next; //找到下一个节点
}
}
void DFSTraverse(AdjListGraph G) //DFS控制函数
{
for (int i = 0; i < G.numVertex; i++)
{
visited[i] = false;
}
for (int i = 0; i < G.numVertex; i++) //保证所有的连通分支 都被访问到
{
if (!visited[i])
{
DFS(G, i);
}
}
}
void BFSTraverse(AdjListGraph G) //广度优先搜索 队列实现
{
queue<int> que;
edgeNode *p;
for (int i = 0; i < G.numVertex; ++i) { //初始化
visited[i]=false;
}
for (int i = 0; i < G.numVertex; ++i) {
if(!visited[i]){
que.push(i); //入队
visited[i]=true; //标记
cout<<G.adjList[i].data<<" ";
while (!que.empty()){ //队列不空 则继续搜索
int t=que.front(); //返回队首元素
que.pop(); //出队
p=G.adjList[t].firstEdge;//通过队头元素查找邻接边
while (p){ ///开始查找
if (!visited[p->adjvex]){
visited[p->adjvex]= true; //标记
cout<<G.adjList[p->adjvex].data<<" "; //输出节点
que.push(p->adjvex); //入队
}
p=p->next;
}//找完了该顶点相连的所以边
}
}
}
}
int main()
{
AdjListGraph G;
createMGraph(&G);
cout << "DFS访问顶点顺序: ";
DFSTraverse(G);
cout << endl;
cout << "BFS访问顶点顺序: ";
BFSTraverse(G);
cout << endl;
return 0;
}
思想和就是DFS 和BFS 的普通思想没什么 特别突出的 ,以后的自己看不懂了 ,请自己画一个邻接表也许就懂了 , 若有大佬感觉我写的不对 或者利用c++有更好的写法 ,请赐教。加油!!!!!Xlz