图的存储结构---(*链式前向星*)
2017-04-10 23:56
288 查看
(写出来仅供随时参考)
优点
实现简单直观
可以直接查询两点之间是否连通
缺点
遍历效率低
不能存储重边/平行边
初始化效率低
大图的空间开销大
优点
可应对点很多的情况
可存储重边
缺点
排序会浪费时间
无法直接判断两点之间是否连通
缺点
内存释放是个问题
优点
代码量少
不易犯错
内存的申请与释放不需要自己处理
链式前向星除了不能直接用起点终点判断是否连通以外,几乎是完美的
References
《ACM-ICPC程序设计系列 图论及应用》
my___github
邻接矩阵
代码引自my_Dijkstratypedef struct ArcCell { int weight; // 邻接矩阵的元素即为图的边的权值 }ArcCell, AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; typedef struct { int vexs[MAX_VERTEX_NUM]; // 存放顶点的数组 AdjMatrix arcs; // 邻接矩阵 int vexnum,arcnum; //图的当前顶点数和弧数 }MGraph;
优点
实现简单直观
可以直接查询两点之间是否连通
缺点
遍历效率低
不能存储重边/平行边
初始化效率低
大图的空间开销大
前向星
int head[maxn]; // 存储起点为Vi的第一条边的位置 struct NODE { int from; int to; int w; // weight }; NODE edge[maxm]; // 比较函数 // 将所有边的信息读入,按照边的起点排序, // 若起点相同,对于相同起点的边按终点排序, // 如果仍有相同,按权值排序 bool cmp(NODE a, NODE b) { if(a.from==b.from && a.to==b.to) return a.w<b.w; if(a.from==b.from) return a.to<b.to; return a.from<b.from; } // 读入数据 cin>>n>>m; for(i=0;i<m;i++) cin>>edge[i].from>>edge[i].to>>edge[i].w; sort(edge,edge+m,cmp); memset(head,-1< 4000 /span>,sizeof(head)); head[edge[0].from]=0; for(i=1;i<m;i++) if(edge[i].from != edge[i-1].from) head[edge[i].from]=i; // 遍历 for(i=1;i<=n;i++) { for(k=head[i];edge[k].from==i && k<m;k++) { cout<<edge[k].from<<" "<<edge[k].to<<" "<<edge[k].w; cout<<endl; } }
优点
可应对点很多的情况
可存储重边
缺点
排序会浪费时间
无法直接判断两点之间是否连通
邻接表(三种实现)
动态建表
代码引自my_Prim// 表边结点 typedef struct ArcNode { int weight; int adjvex; struct ArcNode *nextarc; }ArcNode; // 表头结点 typedef struct VNode { int data; ArcNode *firstarc; }VNode,AdjList[MAX_VERTEX_NUM]; // 图 typedef struct { int vexnum,arcnum; AdjList vertices; }ALGraph;
缺点
内存释放是个问题
STL/vector模拟链表实现
struct EdgeNode { int to; int w; }; vector<EdgeNode> map[maxn]; EdgeNode e; cin>>i>>j>>w; e.to=j; e.w=w; map[i].push_back(e); // 遍历 for(i=1;i<=n;i++) { for(vector<EdgeNode>::iterator k=map[i].begin();k!=map[i].end;k++) { NODE t=*k; cout<<i<<' '<<t.to<<' '<<t.w<<endl; } }
优点
代码量少
不易犯错
内存的申请与释放不需要自己处理
静态建表(链式前向星)
// head数组存储描述点Vi边信息的链的起点在Edges数组的位置 int head ; struct EdgeNode { int to; int w; int next; }; EdgeNode Edges[m]; // 构造链式前向星就是将新加入的结点链在对应链的最开始 // 并修改head数组的对应位置的值 // 信息存储 cin>>i>>j>>w; Edges[k].to=j; Edges[k].w=w; Edges[k].next=head[i]; // 将当前新加入的边的next值 // 设为上条边在Edges中的位置 head[i]=k; // 将当前新加入的边链在之前的边上 // 上两行的操作就和链表中加入一个新结点的操作的意思一样 // 遍历 for(i=1;i<=n;i++) { for(k=head[i];k!=-1;k=edge[k].next) { cout<<i<<" "<<edge[k].to<<" "<<edge[k].w<<endl; } }
No. | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
---|---|---|---|---|---|---|---|---|
head | 10 | 0 | 11 | 6 | 1 | 12 | 7 | 9 |
No. | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
---|---|---|---|---|---|---|---|---|---|---|---|---|
to | 8 | 1 | 3 | 2 | 1 | 3 | 4 | 5 | 7 | 6 | 2 | 7 |
w | 29 | 12 | 11 | 4 | 22 | 17 | 25 | 9 | 7 | 9 | 19 | 4 |
next | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 2 | 3 | 4 | 5 | 8 |
References
《ACM-ICPC程序设计系列 图论及应用》
my___github
相关文章推荐
- 链式前向星存储结构
- 边存储结构体:链式前向星
- 采用链式前向星结构存储的图深搜和广搜算法
- 边存储结构体:链式前向星
- 图的(链式)前向星存储结构
- 图的链式前向星存储结构
- 图的链式前向星存储结构
- 数据结构之C/C++实现二叉树的链式存储
- 链式存储结构和顺序存储结构的区别
- 数据结构之堆栈的链式存储
- 线性表链式存储结构
- 数据结构1——线性表链式存储 java
- 线性表的链式存储结构
- 04.线性表(三)链式存储结构.单链表2
- 数据结构之线性表——队列的链式存储
- [SDUT](2116)数据结构实验之链表一:顺序建立链表 ---链式存储(线性表)
- 队列的链式存储结构与操作
- 栈的链式存储结构及实现
- 链式前向星存储实现BFS
- 数据结构——线性表的伪链表存储(顺序存储链式遍历)