个人学习所记笔记,如有错误请见谅
内容包括邻接表的结构定义,深搜广搜
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
#define MaxVertexNum 100
typedef char VertexType;
//无向邻接表
struct ArcNode { //边表结点
int adjvex; //该弧指向的顶点的位置
struct ArcNode* nextarc; //指向下一条弧的指针
int info; //边的权值
};
typedef struct VNode{ //每个边表所连接的结点
VertexType data;
ArcNode* firstarc;
}VNode,AdjList[MaxVertexNum];
//邻接表结构,
typedef struct {
AdjList vertices;
int vexnum, arcnum;
}ALGraph;
// 初始化图
void InitALGraph(ALGraph& G) {
G.vexnum = 0; // 顶点数初始化为 0
G.arcnum = 0; // 边数初始化为 0
// 初始化邻接表
for (int i = 0; i < MaxVertexNum; i++) {
G.vertices[i].firstarc = nullptr; // 每个顶点的邻接表头指针设为 nullptr
}
}
// 插入顶点
void InsertVertex(ALGraph& G, VertexType vertex) {
if (G.vexnum >= MaxVertexNum) {
cout << "图的顶点数已满,无法插入更多顶点!" << endl;
return;
}
G.vertices[G.vexnum].data = vertex;
G.vertices[G.vexnum].firstarc = nullptr;
G.vexnum++;
}
// 插入边
void InsertArc(ALGraph& G, int v1, int v2, int weight) {
if (v1 >= G.vexnum || v2 >= G.vexnum) {
cout << "顶点索引超出范围!" << endl;
return;
}
// 插入 v2 到 v1 的边
ArcNode* newArc = new ArcNode;
newArc->adjvex = v2;
newArc->info = weight;
newArc->nextarc = G.vertices[v1].firstarc;
G.vertices[v1].firstarc = newArc;
// 插入 v1 到 v2 的边(如果是无向图)
newArc = new ArcNode;
newArc->adjvex = v1;
newArc->info = weight;
newArc->nextarc = G.vertices[v2].firstarc;
G.vertices[v2].firstarc = newArc;
G.arcnum++;
}
// 打印图
void printALGraph(const ALGraph& G) {
for (int i = 0; i < G.vexnum; i++) {
cout << "顶点 " << G.vertices[i].data << " 的邻接点有:";
ArcNode* arc = G.vertices[i].firstarc; //初始化 arc 为当前顶点 v 的第一个邻接顶点。
while (arc != nullptr) {
cout << " (" << G.vertices[arc->adjvex].data << ", 权值: " << arc->info << ")";
arc = arc->nextarc;
}
cout << endl;
}
}
// 深度优先遍历的递归函数
void DFS(ALGraph& G, int v, vector<bool>& visited) {
// 访问当前顶点
cout << G.vertices[v].data << " ";
visited[v] = true;
// 遍历当前顶点的所有邻接顶点
ArcNode* arc = G.vertices[v].firstarc;
while (arc != nullptr) {
if (!visited[arc->adjvex]) {
DFS(G, arc->adjvex, visited);
}
arc = arc->nextarc;
}
}
// 深度优先遍历的入口函数
//这个函数是深度优先遍历的入口点。它遍历图中的所有顶点,
//并确保即使图是非连通的,所有顶点都能被访问到。
void DFSTraverse(ALGraph& G) {
vector<bool> visited(G.vexnum, false); // 记录每个顶点是否被访问过
// 遍历所有顶点,防止图中有不连通的部分
//如果当前顶点 i 尚未被访问,则调用 DFS 从这个顶点开始遍历。
for (int i = 0; i < G.vexnum; i++) {
if (!visited[i]) {
DFS(G, i, visited);
}
}
}
//总结
//DFS 函数负责从一个顶点递归地访问所有相邻的未访问顶点。
//DFSTraverse 函数确保了图中的每个顶点都被访问,即使图是非连通的。它通过调用 DFS 函数来实现深度优先遍历。
// 广度优先遍历
void BFS(const ALGraph& G, int startVertex) {
if (startVertex >= G.vexnum) {
cout << "起始顶点索引超出范围!" << endl;
return;
}
vector<bool> visited(G.vexnum, false); // 记录顶点是否被访问
queue<int> q; // 用于 BFS 的队列
// 从起始顶点开始
visited[startVertex] = true;
q.push(startVertex);
while (!q.empty()) {
int v = q.front();
q.pop();
cout << G.vertices[v].data << " "; // 打印当前顶点
ArcNode* arc = G.vertices[v].firstarc;
while (arc != nullptr) {
if (!visited[arc->adjvex]) {
visited[arc->adjvex] = true;
q.push(arc->adjvex);
}
arc = arc->nextarc;
}
}
cout << endl;
}
int main()
{
ALGraph G;
InitALGraph(G);
// 示例:插入顶点 A 和 B
InsertVertex(G, 'A');
InsertVertex(G, 'B');
InsertVertex(G, 'C');
InsertVertex(G, 'D');
InsertVertex(G, 'E');
InsertVertex(G, 'F');
InsertVertex(G, 'G');
// 示例:插入边 A-B,A-C,B-D,C-D,权值为 10
InsertArc(G, 0, 1, 10);
InsertArc(G, 0, 2, 10);
InsertArc(G, 1, 3, 10);
InsertArc(G, 1, 4, 10);
InsertArc(G, 2, 5, 10);
InsertArc(G, 2, 6, 10);
// 打印图的结构
printALGraph(G);
// 执行深度优先遍历
cout << "深度优先遍历结果:" << endl;
DFSTraverse(G);
cout << endl;
//执行广度优先遍历:
cout << "广度优先遍历的结果为:" << endl;
BFS(G, 0);
return 0;
}
以下是运行结果
上面是邻接表的显示
下面是深搜和广搜的结果
由于邻接表插入数据是头查,所以遍历结果与普通的邻接矩阵不同,需要仔细研究