树与图的存储
树与图的存储
1. 树与图的定义
树实际上是一种特殊的图,名为无环连通图。因此,我们只需要了解图的存储方式即可。
图分为:有向图和无向图。
假设,给定两个节点a,b:
1. 在有向图中,a->b 指:a可以走到b,而b不可以走到a。b->a同理。
2. 在无向图中,a-b指:a->b和b->a
因此,我们也可以把无向图看做是特殊的有向图。因此,我们只考虑有向图的存储即可。
2. 有向图的存储方式
有向图有两大存储方式:
1. 邻接矩阵
这种方式使用较少,实现简单,开一个二维数组即可。数组中的每一个元素存储着边的信息。如果图中每条边没有权重,则元素(边)只有0和1两个值。0代表没有边,1代表有边。如果有权重,元素的值就代表边的权重。如果元素的值为负无穷(或者是其它的数,需要具体问题具体分析),那么就代表没有这个边。邻接矩阵耗费的空间复杂度很大,一般是O(n²),适合存储稠密图,不适合稀疏图。邻接矩阵无法存储重边(多个相同边),只能保留一个边进行存储,如果用于求解最短路问题的话,一般保留权重最小的边即可。
2. 邻接表
这种方式使用较多。如果有n个节点,那么对于每一个节点都需要开一个单链表。单链表中的节点存储的就是这个节点所邻接的边。具体看上图。跟哈希表的拉链法差不多。
3. 模板
/*树与图的存储
树是一种特殊的图,与图的存储方式相同。
对于无向图中的边ab,存储两条有向边a->b, b->a。
因此我们可以只考虑有向图的存储。
*/
//(1) 邻接矩阵:g[a][b] 存储边a->b
//(2) 邻接表:
// 对于每个点k,开一个单链表,存储k所有可以走到的点。h[k]存储这个单链表的头结点
int h[N], e[N], ne[N], idx;
// 添加一条边a->b
void add(int a, int b)
{
e[idx] = b, ne[idx] = h[a], h[a] = idx ++ ;
}
// 初始化
idx = 0;
memset(h, -1, sizeof h);
作者:gao79138
链接:https://www.acwing.com/
来源:本博客中的截图、代码模板及题目地址均来自于Acwing。其余内容均为作者原创。
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具