持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第33天,点击查看活动详情
手把手教学考研大纲范围内图的存储和遍历 22考研大纲数据结构要求的是C/C++,笔者以前使用的都是Java,对于C++还很欠缺, 如有什么建议或者不足欢迎大佬评论区或者私信指出 初心是用最简单的语言描述数据结构
Talk is cheap. Show me the code. 理论到处都有,代码加例题自己练习才能真的学会
2.2、邻接表
当一个图中,边的数量少 时(也叫做稀疏图),用邻接矩阵会很 浪费空间 ,这时候 邻接表 就出来了
邻接表结构:
头结点包含一个 顶点 和一个指向 边(表结点) 的指针
表结点包含一个 顶点 ,一个指向 下一条边(表结点) 的指针 和 边的权值(图没有权值)
Tips: 这里指向的边,都是 以当前 头结点 顶点 直接联系 的边
eg:
比如这个以 V1 直接联系的点是 V4 和 V2 ,所以表结点是 V4 和 V2
无向图
有向图
解释:
0-4 代表 a-e
邻接矩阵中,是以顶点为起点的关系(逆邻接矩阵,以顶点为终点的关系)
0 -> 1 (a->b) 的边,权重 e1
0 -> 2 (a->c) 的边,权重 e2
0没有指向其他方向的边了
多分析分析这几个图,其实很容易懂得
邻接表示例代码
代码:
#include "iostream"
using namespace std;
#define MAXNum 100 //顶点数最大为100
typedef struct ArcNode { //定义边结点结构体:顶点的邻点adjvex,边的权重,下一个边结点的指针
int adjvex;
int info;
struct ArcNode *nextarc;
} ArcNode;
typedef struct VNode { //定义表头结点结构体:顶点data,指向边结点的指针
int data;
ArcNode *firstarc;
} VNode, AdjList[MAXNum]; //AdjList 是表头结点的数组类型
typedef struct { //定义邻接表结构体:表头结点数组,顶点数量和边数量
AdjList vertices;
int vexnum, arcnum;
} ALGraph;
//找到顶点在表头结点的下标
int getGraphIndex(ALGraph G, int targetnode) {
for (int i = 0; i < G.vexnum; i++) {
if (G.vertices[i].data == targetnode) {
return i;
}
}
return -1;
}
//创建邻接表
bool createGraph(ALGraph &G) {
cout << "请输入顶点数量和边的数量" << endl;
cin >> G.vexnum >> G.arcnum; //输出顶点数量和边数量
for (int i = 0; i < G.vexnum; i++) { //输出顶点,并且设置指向的边结点为空
cout << "请输入顶点的值" << endl;
cin >> G.vertices[i].data;
G.vertices[i].firstarc = NULL;
}
int v1, v2, i1, i2;
for (int i = 0; i < G.arcnum; i++) { //输入两个相邻的顶点
cout << "请输入新建边相邻的两个结点" << endl;
cin >> v1 >> v2;
i1 = getGraphIndex(G, v1); //找到两个顶点的下标
i2 = getGraphIndex(G, v2);
ArcNode *p1 = new ArcNode; //创建p1边结点,让v1表头结点指向p1边结点
p1->adjvex = v2; //p1设置邻接点为v2
p1->nextarc = G.vertices[i1].firstarc; //采用头插法,如果采用尾插,每次都要循环到当前表头结点的最后一个末尾边结点才能插入
G.vertices[i1].firstarc = p1;
ArcNode *p2 = new ArcNode; //与上面同理
p2->adjvex = v1;
p2->nextarc = G.vertices[i2].firstarc;
G.vertices[i2].firstarc = p2;
}
return true;
}
//输出邻接表
void printGraph(ALGraph G) {
for (int i = 0; i < G.vexnum; i++) {
cout << G.vertices[i].data << " : ";
ArcNode *temp = G.vertices[i].firstarc;
while (temp != NULL) {
cout << "下一个顶点:" << temp->adjvex << " ";
temp = temp->nextarc;
}
cout << "下一个顶点为空\n";
}
}
int main() {
ALGraph G;
//输入样例:4 3 1 2 3 4 1 2 1 3 2 3
createGraph(G);
printGraph(G);
}
输入输出样例:
/home/a1439775520/CLionProjects/Graph/cmake-build-debug/Graph
请输入顶点数量和边的数量
4 3
请输入顶点的值
1
请输入顶点的值
2
请输入顶点的值
3
请输入顶点的值
4
请输入新建边相邻的两个结点
1 2
请输入新建边相邻的两个结点
1 3
请输入新建边相邻的两个结点
2 3
1 : 下一个顶点:3 下一个顶点:2 下一个顶点为空
2 : 下一个顶点:3 下一个顶点:1 下一个顶点为空
3 : 下一个顶点:2 下一个顶点:1 下一个顶点为空
4 : 下一个顶点为空
Process finished with exit code 0