邻接表

图---删除指定弧(邻接表)

为君一笑 提交于 2019-12-02 16:32:37
typedef struct arcnode //边节点 { int adjvex; struct arcnode* nextarc; int weight; }arcnode; typedef struct vnode //顶点节点 { int data; arcnode* firstarc; }vnode, adjlist[100];//邻接表 typedef struct Graph //图结构 { adjlist ver; int vernum, arcnum; }Graph; void Delete(adjlist g, int i, int j) { arcnode *p,*pre; p = g[i].firstarc; pre = NULL; while (p) { if (p->adjvex == j)//找到弧 { if (pre == null)//此节点第一条弧 { g[i].firstarc = p->nextarc; } else//删除操作 { pre->nextarc = p->nextarc; free(p); } } else//未找到,继续搜索 { pre = p; p = p->nextarc; } } p = g[j].firstarc;//无向图搜索两个方向 pre = NULL; while (p) { if (p->adjvex ==

邻接表之链式前向星

喜欢而已 提交于 2019-11-29 12:29:33
链式前向星比vector邻接表在内存性能和时间性能上更好。 链式前向星用法详见以下模板代码: #include<bits/stdc++.h> using namespace std; const int maxn=1e3+10;//最大点数 const int maxm=1e6+10;//最大边数 struct node{int to,w,next;}edge[maxm];//边集,to终点,w边权,next同起点的上一条边的编号 int n,m,head[maxn];//输入n个点,m条边 struct Chain_Forward_Star{//链式前向星 int cnt; void init(){//初始化 cnt=0; memset(head,-1,sizeof(head));//初始化为-1 } void add(int u,int v,int w){//加边,u起点,v终点,w边权 edge[cnt].to=v; edge[cnt].w=w; edge[cnt].next=head[u];//同样以u为起点的上一条边的编号 head[u]=cnt++;//更新以u为起点的上一条边的编号 } }CFS; int main() { int u,v,w; cin>>n>>m; CFS.init(); for(int i=1;i<=m;i++){ cin>>u>>v>>w;/

邻接表

試著忘記壹切 提交于 2019-11-28 23:08:30
数组实现邻接表 思路: 临接表是储存一条边的起点,终点,权重,用数组实现时用srtuct数组e中储存上述内容。 在储存时,我们储存起点的编号和终点的编号。 为了方便的遍历各点,我们还需要储存下一条边的位置。 emmmm非常抽象,我都不知道自己解释的啥玩意。 我们来用图片、代码和实例来说话(原谅我的画风) int head[7], total, n, m; struct edge { int u, v, w; }e[10]; 左边的条条是数组head,储存的是每个点第一个出边在数组e中的位置 右边的框框是数组e,每个格子储存3个元素,u起点,v终点,w权重 我们假设一共有6个点,9条边。 那我们一共就要储存6个点的第一条出边在e中的位置,即head[6+1]注意数组的结尾。 9条边分别储存在数组e中,即e[9+1]结尾同理。 解释完了变量我们开始输入 数据: 6 9 //点数和边数 1 2 1 //u v w w权重这里不多说,最后加上就行 1 3 12 2 3 9 2 4 3 3 5 5 4 3 4 4 5 13 4 6 15 5 6 4 1 2 1 点1连向点2权重为1 我们将head[1]赋值为1,表示点1的第一条出边储存在e[1]中。 那我们第一条边的起点有了,终点2呢? 我们将e[i]的元素u赋值为2,表示这条边的中点为2。 w为权重不解释。v马上解释

C++ Kruskal算法

拈花ヽ惹草 提交于 2019-11-27 14:33:18
kruskal与prim都是用于图的最小生成树,prim从点出发,kruskal从边出发,不同的角度解决问题,对应不同的应用场景。prim适用于点少边多的图(稠密图),kruskal 使用于边少点多的图(稀疏图),中心思想就是先排序所有边,从最小寻找两点对应的根,再把根相连,若根相同,则会成环,这在树中是不被允许的。树中的边的数目为点的数目-1,则完成最小生成树。以下代码用邻接矩阵实现,用邻接表更容易实现,我就不打邻接表的实现了,很简单 #include<iostream> #define MAX_VERTEX 100 #define INFINITE 65535 using namespace std; //common int _count=0; struct Side{ int start; int end; int weight; }; Side* _pSide; int vertex_parent[MAX_VERTEX]; int GetParent(int i){ int k=vertex_parent[i]; while(k!=0){ i=k; k=vertex_parent[k]; } return i; } //array char vertex_infos[MAX_VERTEX]; int matrix[MAX_VERTEX][MAX_VERTEX]; void

图论之邻接表的数组实现

可紊 提交于 2019-11-26 22:25:04
虽然邻接矩阵真的很方便,很简单,很利于理解,但却有着一些重大缺陷; 当我们遇到的是一张稀疏图的时候,邻接矩阵就造成严重的空间浪费,更直接一点,就是根本存不下来; 这个时候就不得不考虑其他存图方式了,这个时候另一种流行的存图方式就登场了——邻接表,当然使用vector数组也是一种良好的选择; 邻接表的实现可以通过链表或数组的方式实现,我这里主要讲数组的实现方法; 首先,有三个数组,分别为u[max],v[max],w[max]分别代表着每条边的起点,终点,权重,而下标则代表着边的编号; 然后设立first[max],next[first]这两个数组; first数组存储的是边的编号,下标代表的是边的起始结点; next数组存储的是编号为i的前一条边的编号,其中i就是下标; 那么插入一条边的过程就是这样的: 首先将边读入到u,v,w这三个数组中; 然后根据u找到first数组中下标为u的那栏,如果为空,就将边的编号直接加入其中,否则,将这编号放入对应的next数组中,将first数组中存新加入的结点编号; int n,m;//结点数目,边的数目 int u[1000],v[1000],w[1000];//边的起点,终点,权重 int first[1000],next[1000]; cin>>n>>m; for(int i=1;i<=n;++i) { first[i]=-1;//将

数据结构-图-C语言-邻接表

烈酒焚心 提交于 2019-11-26 22:24:05
数据结构-图-C语言-邻接表 # include <stdio.h> # include <stdlib.h> # define Max 100 typedef int Vertex ; typedef int WeightType ; /** * * @author Caedios * @attr v1 顶点v1,即有向边v1->v2 * @attr v2 顶点v2,即有向边v1->v2 * @attr weight 边的权重 * */ struct ENode { Vertex v1 , v2 ; WeightType weight ; } ; typedef struct ENode * pENode ; /** * * @author Caedios * @attr subNum 邻接点下标 * @attr weight 边权重 * @attr pVNode 指向下个邻接点 * */ struct VNode { Vertex subNum ; WeightType weight ; pVNode nextVNode ; } ; typedef struct VNode * pVNode ; /** * * @author Caedios * @attr headVNode 邻接表的头顶点指针 * */ struct HeadVNode { pVNode headVNode

【图论】数组模拟邻接表存储(链式前向星)

梦想与她 提交于 2019-11-26 22:22:48
图的邻接表存储法 又叫链式存储法 可以用数组模拟 定义 struct edge{ int next; //下一条边的编号 int to; //这条边到达的点 int dis; //这条边的长度 }edge[size]; //COYG 核心代码 加入一条从from到to距离为dis的单向边 inline void add( int from , int to, int dis) { edge[++num].next=head[ from ]; edge[num].to=to; edge[num].dis=dis; head[ from ]=num; } //COYG 举一个例子吧 别喷图 图上每一个边上的数字 既是编号 也是长度 就是这样一个简单图 按照上面的代码 存储完之后各数组的情况是这样的 next数组是这样存的:对于一条边 假如之前已经加入过与这条边同一起点的边 则储存最靠后的同起点边的编号 如果之前没有加入过任何与这条边同起点的边 则next数组的值为0 dis数组是存储的当前这条边的长度 to数组很好理解 它存储的就是你现在输入的这条边的末端点 head[i]代表第i个点为端点连接的最后一条边的编号 主要要点就这些 继续努力 来源: CSDN 作者: ars4me 链接: https://blog.csdn.net/qq_36303472/article/details

54-图的邻接表存储结构

筅森魡賤 提交于 2019-11-26 22:22:35
  我们知道图的存储结构有邻接矩阵存储方法和邻接表存储方法,而对于邻接矩阵我们已经学习过了,本篇将主要介绍图的邻接表存储结构。 图1-图的邻接表存储结构 1. 邻接表存储带权有向图 图2-邻接表存储有向图    邻接表存储方法是对图中每个顶点i建立一个单链表,将顶点i的所有邻接点链接起来,然后再给每个单链表上附设一个表头节点(表示顶点信息),将所有表头节点构成一个数组(顺序表),下标为i的元素表示顶点i的表头节点,因此不难看出单链表中的每个节点代表着一条边,我们称之为边节点 。 2. 邻接表的存储结构   从邻接表存储方法我们可知,图的邻接表存储方法是一种 顺序分配和链式分配 相结合的存储方法。而且邻接表中有两类节点:表头节点和单链表中的边节点。   如图2所示,在表头节点中的data域表示每个顶点的信息,firstarc域用于指向单链表的第一个边节点(即相关联的邻接点),而单链表中的每个边节点又包括了adjvex域,nextar域,info域。   adjvex域用于存储某顶点的邻接点,而nextar域则用于指向单链表中的下一个边节点,而info域则用于存储边节点信息,如权值。 由以上这些信息,我们可以定义邻接表存储结构,如下所示: typedef struct ANode { int adjvex; //记录某顶点的邻接点 struct ANode *nextarc; /

图的储存--邻接表

不想你离开。 提交于 2019-11-26 22:21:52
我学过的图的存储方式有两种,一种是用邻接矩阵存储,邻接矩阵的优点是可以快速判断两个顶点之间是否存在边,可以快速添加边或者删除边。但是他也有很明显的不足,那就是邻接矩阵的大小只能根据点来定义,若一个图的点较多但是边很少,如果用邻接矩阵来储存会浪费很大多的空间资源,这时我们的 邻接表登场了!!! 邻接表就是根据边来定义大小的。 介绍一下邻接表,邻接表可以用结构体 + 指针实现 也可以由结构体 + 数组实现 今天讲一下 结构体 + 数组 来实现邻接表 结构体模板 : #include<stdio.h> #include<stdlib.h> #include<string.h> #define MAXN 10000 struct { int value; //用来存边的权值 int to; //用来存边的末端 int next;// 用来储存下一条边的编号 }edges[MAXN]; int cnt = 0; //第一边的编号为零 int head[MAXN]; //储存以 i 为 始点的边的编号 void init(){ memset(head,-1,sizeof(head)); //初始化每个点均没在边中 } void add(int u,int v,int value){ edges[cnt].to = v; //编号为 cnt的边的末端 edges[cnt].value =

图的常用存储结构----邻接表

允我心安 提交于 2019-11-26 22:21:19
Def:邻接表是图的链式存储结构,其意义是把每个邻接于vi的顶点连接成一个单链表,这个单链表就成为该顶点的邻接表。 实现方法: 1、动态建表 Method:对于每个读入的边建立一个邻接表节点的对象,加入到相应的邻接表中,同时动态申请内存。 Property: (1)对于无向图的邻接表,每个顶点度就是该顶点的邻接表中节点数。 (2)对于有向图,第i个链表(邻接表)中的节点数是vi节点的出度;求其入度需要遍历整个邻接表或者建立你邻接表。 (3)对于同一个图,输入边的顺序不同,其邻接表也不一样。 AnalystS: (1)时间效率:O(m),空间效率O(m)。 (2)根据需求动态申请内存,需要多少内存就申请多少。 AnalystW: (1)需要考虑内存的释放问题。 (2)一次性申请内存与随机申请再申请总数一定的时候前者消耗时间少。 (3)判断任意两个顶点之间是否有边连接时需要搜索这两个点的链表。 #include #include using namespace std; #define maxn 100 struct Edgenode //邻接表节点 { int to;//边指向的终点 int w;//该边的权值 Edgenode *next;//指向当前点上一次已经保存的邻接点,把该点的所有邻接点连到一起 }; struct Vnode //表头节点 { int from; /