图的存储与遍历笔记
树与图的存储与遍历(邻接表)笔记
树是一种特殊的图,树没有环且相互连通
图分为有向图和无向图,无向图可以转化为双向的有向图
图的存储
这里介绍一种存储图的方式:邻接表
数组模拟:
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]); } } }
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· 推荐几款开源且免费的 .NET MAUI 组件库
· 实操Deepseek接入个人知识库
· 易语言 —— 开山篇
· Trae初体验