图的存储与遍历笔记

树与图的存储与遍历(邻接表)笔记

树是一种特殊的图,树没有环且相互连通

图分为有向图和无向图,无向图可以转化为双向的有向图


图的存储

这里介绍一种存储图的方式:邻接表

数组模拟:

int h[N], e[N], ne[N], idx;

把图的每个顶点都开一条单链表,记录在 h[N] 中,这个顶点能连通到的其他点就存储在这个链表里面

e[N] 存储的是能够连通的点,ne[N] 存储的是下一个节点的位置,作用是连通整个链表,使我们能够访问数据

idx 则记录我们当前使用到了哪个空节点

使用vector

vector<int> node

直接对每个节点都开一个vector


添加有向图的一条边

数组模拟:add 函数,在单链表的头节点后插入节点

void add(int a, int b){
e[idx] = b, ne[b] = h[a], h[a] = idx++;
}

第一步将当前空节点的值 e[idx] 设置为我们 a点 能连通到的 b点 ,然后把 b点 的下一个节点指向原来 h[a]头节点指向的位置

最后把头节点指向我们 add 的空节点,idx++ 移动到下一个空节点

使用vector

void add(int a, int b) {
node[a].push_back(b);
}

同理,添加无向图的一条边时,我们只需要 add(a, b)add(b, a) 即可


图的遍历

搜索每个点时,只能搜索一次这个点,保证路径不重复
使用 st[N] 来记录每个节点的状态(是否搜索过)

int st[N];

DFS深度优先遍历:

每次都递归搜索当前节点,如果这个节点没有能连通的节点,或能连通的节点已经被搜索过了,则返回

以洛谷B3862为例:

数组模拟:

void dfs(int x,int now) {
ans[x] = max(ans[x], now);
st[now] = 1;
for (int i = h[now]; i != -1; i = ne[i]) {//从这个节点的链表头开始,一直遍历到空节点
if (!st[e[i]]) //e[i]为当前可连通到的点
dfs(x, e[i]);
}
}

使用vector

void dfs(int x, int now) {//x为当前考虑的节点,now为当前走到的节点
ans[x] = max(ans[x], now);//重置答案
st[now] = 1;//将搜索过的点标记
if (node[now].empty()) return;//如果当前走到的节点没有可连通的节点,于是返回
for (int i = 0; i < node[now].size(); i++)//遍历当前走到的节点可连通的节点
if (!st[node[now][i]]) dfs(x, node[now][i]);//如果可连通的节点没有被搜索过,就走到它
}

BFS广度优先搜索:拓扑排序

每次只向下搜索一步,将走到的节点放进队列,队列为空时,判断加入队列的点数是否为总节点数,如果不相同说明存在环
我们进行拓扑排序时,需要记录每个点的入度,即有多少条边可以走到这个节点(节点的入度为 \(0\) ,则它的拓扑序为局部最高

以洛谷B3644为例:

记录每个点的入度:

int d[N];
add(x, y);//x能走到y节点,添加一条x指向y的单向边
d[y]++;//y节点的入度加1

数组模拟:

void topsort(void) {
for (int i = 1; i <= n; i++)
if (!d[i])
q.push(i);
while (!q.empty())
{
int tt = q.front();//取出队头元素
printf("%d ", tt);//输出拓扑序
q.pop();//弹出队头元素
for (int i = h[tt]; i != -1; i = ne[i]) {
d[e[i]]--;
if (d[e[i]] == 0)
q.push(e[i]);//将入度为0的点放进队列
}
}
}

使用vector

void topsort(void) {
for (int i = 1; i <= n; i++)
if (!d[i])
q.push(i);
while (!q.empty())
{
int tt = q.front();
printf("%d ", tt);
q.pop();
for (int i = 0; i < node[tt].size(); i++) {
d[node[tt][i]]--;
if (d[node[tt][i]] == 0)
q.push(node[tt][i]);
}
}
}
posted @   才瓯  阅读(30)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· 推荐几款开源且免费的 .NET MAUI 组件库
· 实操Deepseek接入个人知识库
· 易语言 —— 开山篇
· Trae初体验
点击右上角即可分享
微信分享提示