用邻接链表存储无向图和有向图
来源:互联网 发布:淘宝聊天记录 编辑:程序博客网 时间:2024/06/05 09:29
上一篇文章我们说到用邻接矩阵存储有向图和无向图,这种方法的有点是很直观的知道点与点之间的关系,查找的复杂度是为O(1)。但是这种存储方式同时存在着占用较多存储空间的问题,
邻接矩阵存储很好理解,但是,有时候太浪费空间了,特别是对于顶点数多,但是关联关系少的图。
举个极端的例子。
下图中,5个顶点都是孤立的,然而为了存储边的信息,要分配一个5X5的矩阵。本来一条边都没有,没必要用存储空间来存储边,但还要分配额外的空间。
用邻接表则可以避免这种浪费。邻接表用动态表结构存储边,更加灵活:有一个边就分配一个空间去存储,没有就不分配。
我们仍然用邻接矩阵中那个图的例子来说明邻接表的构建思想。
邻接表只需要一个数组,但是这个数组有点复杂,需要解剖一下。如下图。
可以发现,用邻接表存储时,图中的每一个节点 不仅要存储本顶点的数据data,还要存储一个表,这个表存储了此顶点的所有临接点的索引。2点确定一线,那么就能存储此节点相关的所有的边了。
下面我们用到C++库中的vector来实现indexlist。代码如下:
#include<stdio.h>#include<vector>#define MAX_VERTEX 4using std::vector; //使用C++标准库中的vector来作为list,它实质就是一个顺序表 typedef char DataType;typedef struct node{ DataType data; //顶点数据 vector<int> indexList; //存储顶点邻接点索引的 表 }Node;typedef Node* UListGraph;/********************************/void UListGraph_init(UListGraph*pGraph);void UListGraph_create(UListGraph graph);void UListGraph_show(UListGraph graph);void UListGraph_destroy(UListGraph*pGraph);int main(void){ UListGraph g; UListGraph_init(&g); UListGraph_create(g); UListGraph_show(g); UListGraph_destroy(&g); return 0;}void UListGraph_init(UListGraph*pGraph){ (*pGraph) = new Node[MAX_VERTEX];}void UListGraph_create(UListGraph graph){ for (int i = 0; i < MAX_VERTEX; ++i) //填充顶点数组 { printf("输入第%d个顶点值\n",i+1); scanf(" %c", &(graph[i].data)); } for(int i=0;i<MAX_VERTEX;++i) for(int j=i+1;j<MAX_VERTEX;++j) { printf("如果元素%c和%c之间有边,请输入1,否则输入0",graph[i].data,graph[j].data); int opt; scanf("%d",&opt); if(opt==1) { graph[i].indexList.push_back(j); graph[j].indexList.push_back(i); } }}void UListGraph_show(UListGraph graph){ printf("顶点元素如下:\n\n"); for(int i=0;i<MAX_VERTEX;i++) { printf("%c\t",graph[i].data); } printf("\n\n"); for(int i=0;i<MAX_VERTEX;i++) { printf("元素%c的邻接点 :",graph[i].data); Node tnode = graph[i]; for(int k=0;k<tnode.indexList.size();++k) { printf("%c\t",graph[tnode.indexList[k]].data); } putchar('\n'); }}void UListGraph_destroy(UListGraph*pGraph){ delete (*pGraph); *pGraph = NULL; }2、有向网用邻接链表存储
邻接表对于无向图来说很适用,但是对于有向图来说就不适用了,因为邻接表中,每一个节点的IndexList只能存储一种状态的弧,出弧或者入弧(逆邻接表),那怎么将一个顶点的出入弧都存储起来呢?
那就是将邻接表和逆邻接表都用起来,也就是一个节点需要存储:①data,②inArcList,入弧记录表,③outArcList,出弧记录表
实现代码如下:
#include<stdio.h>#include<vector>using std::vector;#define MAX_VERTEX 4 typedef char DataType;typedef struct arc{ int headVertex; //此条弧的头尾结点的index int tailVertex; //此条弧的头尾结点的index //WeightType weight; //此弧的附加信息,比如权重,这里是有向图,不是网,所以不需要weight}Arc;typedef struct node{ DataType data; //顶点数据域 vector<Arc> outArc; //此顶点的所有 出度 弧 表 vector<Arc> inArc; //此顶点的所有 入度 弧 表 }Node;typedef Node* Graph;void Graph_init(Graph* pG);void Graph_create(Graph g);void Graph_show(Graph g);void Graph_destroy(Graph*pg);int main(void){ Graph g; Graph_init(&g); Graph_create(g); Graph_show(g); return 0;}void Graph_init(Graph* pG){ (*pG) = new Node[MAX_VERTEX]; if(*pG == NULL) { //exit(-1); }}void Graph_create(Graph g){ int opt; for (int i = 0; i < MAX_VERTEX; ++i) //填充顶点数组 { printf("输入第%d个顶点值\n",i+1); scanf(" %c", &(g[i].data)); } for(int j=0;j<MAX_VERTEX;++j) for(int i=j+1;i<MAX_VERTEX;++i) { printf("若元素%c有指向%c的弧,则输入1,否则输入0\t",g[j].data,g[i].data); scanf("%d",&opt); if(opt==1) { Arc* parc = new Arc; parc->headVertex = i; parc->tailVertex = j; g[j].outArc.push_back(*parc); g[i].inArc.push_back(*parc); } printf("若元素%c有指向%c的弧,则输入1,否则输入0\t",g[i].data,g[j].data); scanf("%d",&opt); if(opt==1) { Arc* parc = new Arc; parc->headVertex = j; parc->tailVertex = i; g[i].outArc.push_back(*parc); g[j].inArc.push_back(*parc); } }}void Graph_show(Graph g){ for (int j = 0; j <MAX_VERTEX; ++j) { printf("顶点数据%c\n",g[j].data); printf("发射:"); for(int i=0;i<g[j].outArc.size();++i) { printf("%c\t",g[g[j].outArc[i].headVertex].data); } putchar('\n'); printf("接收:"); for(int i=0;i<g[j].inArc.size();++i) { printf("%c\t",g[g[j].inArc[i].tailVertex].data); } printf("\n\n"); } }void Graph_destroy(Graph*pg){ delete (*pg); *pg = NULL; }
0 0
- 用邻接链表存储无向图和有向图
- 用邻接表存储有向图
- 邻接表-建立无向图、无向网、有向图、有向网
- 邻接表存储无向图
- 无向图的邻接表存储
- 利用邻接表存储结构创建一个图(有向、无向)
- C++邻接表实现无向图、有向图
- 有向图的邻接表存储
- 邻接表无向图
- 用邻接表实现无向图
- 有向图-邻接表
- 用邻接表存储有向图,并输出各顶点的出入和入度
- 用邻接表存储有向图实现的dfs和bfs
- 无向图邻接表的存储结构
- 邻接多重表存储无向图以及有关操作
- 无向图的邻接多重表存储结构
- 无向网图的邻接表存储结构
- 数据结构--无向图的邻接多重表存储结构
- Http Range请求头格式
- A
- c++ String实现 基于Vector
- SSM框架——详细整合教程(Spring+SpringMVC+MyBatis)
- Keras + Windows +Anaconda2-4.2.0 深度学习框架快速搭建
- 用邻接链表存储无向图和有向图
- win10创意者更新是什么 Win10创意者更新升级方法
- Linux Ubuntu从零开始部署web环境及项目 -----tomcat+jdk+mysql (二)
- redirect和forward的区别
- 定时5秒自动换图和背景加onclick点击左右切换图片和背景
- 买糖果(京东2016实习生真题)
- platform按键驱动学习
- SSM框架——以注解形式实现事务管理
- Unbuntu16.04.1如何启动、关闭hadoop