链表、链式前向星

讲链表的时候就卡在这里了,最短路又卡在链式前向星上了,毕竟是图论基础,觉得还是有必要写一写防止下次再懵。

链表都是头插法!!即每次我们给他插一个头。

普通链表

先初始化令head=-1,idx=-1.

void add_tohead(int x) {		//向链表头插入一个元素
	e[idx] = x ;  //新建一个节点
	ne[idx] = head ;  	//新建节点的next指向原来的head
	head = idx ; 	//head指向我新建的节点
	idx ++ ;
}

6c7d15e236b14c9ab15e8fb5784ac51a.jpeg

e数组存的是我们想要的数值或者其他的,ne数组存我们希望的顺序,若不改变则是上一个元素的下标,每次借用head指向最新的元素下标,再次加入借用head更新ne数组并再次更新head。

void remove(int x) {	//删除一个元素的后一个元素
	ne[x] = ne[ne[x]] ; 	//当前节点的next指向原来的next的next
}//ne数组里存的是上一个元素的下标

63f8290315fd49babca63fe4d2eba978.png

 我们将ne数组中下标为x的元素更新为下标为该元素的元素,看图解,这样我们在访问时,访问到e数组下标为x的元素后,i=ne[x],即为y,相当于我们没有删除e数组的元素而是跳过了他,使得遍历无法访问到该值。

void add(int k, int x) {   //在第k个插入的数后面添加一个元素
	e[idx] = x ;  //新建一个节点
	ne[idx] = ne[k] ; 	//新建节点的next指向原来next[k]
	ne[k] = idx ; 	//原来的next[k]指向新建的节点 26行和27行不能调换!
	idx ++ ;
}

8d4b58a5cf29422ab45533b3737e4b2a.jpeg

 新建一个e数组元素,同样地,不改变e数组而是改变ne数组(改变访问顺序),看图解,我们访问到ne[k]时,其实是访问了e[idx]即新建的元素,之后i更新为ne[idx],此时访问的是e[t],然后继续回归顺序。这样就达到了在k之后新插一个元素的要求。

for (int i = head ; i != -1 ; i = ne[i]) {
		cout << e[i] << " \n"[ne[i] == -1] ;
	}

遍历的实现。当ne[i] == -1的时候就说明已经到达链表尾部(或者也可以不初始化,中间句直接i就可以),即第一个插入的元素已进行循环,该链表已遍历。

链式前向星

最短路问题 dijkstra算法建图

struct node {
	int to, nex, val;   
} arr[N];
int tot = 0;
int dis[N];
bool vis[N];

void add(int u, int v, int c) {    //表示u-v间有一条长度为c的路
	arr[++tot].to = v;
	arr[tot].val = c;
	arr[tot].nex = head[u];
	head[u] = tot;
}

fd45b81bd44948089d183881a7a5e758.jpeg

主要理解head[u]存的到底是什么?

head[u]存了所有以u为一个端点的边。边是怎么存的呢?我们这里用结构体数组存了每一条边,所以准确地说, head[u]存了所有以u为端点的结构体下标。

再注意一点,我们的结构体存储的真的是准确的边吗?并不是,我们只存了他的一个端点和距离,而用本该是另一个端点的位置存储了该端点的上一条边的下标。

为什么?

因为我们建图是为了之后的遍历,我们的遍历方式是选点,遍历该点的所有边找最短路,那么我们在建图的时候就应该选择可以找出一个点的所有边的方式,这就是链式前向星。此时,每条边出现/输入的顺序对结果无影响(反正是要遍历)。

最后一点注意!!题目要求是无向图的时候,我们要建双向边,上述代码建了一个单向的边,即我们把该边存入了u端点而未存入v端点,所以最好把建图函数拎出来,主函数输入一次,建两次边。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
前向星和链式前向星区别在于实现方式和数据结构的不同。 前向星是一种存储图的边的数据结构,它使用两个数组来存储边的信息。一个数组存储每个顶点的第一条边的索引,另一个数组存储每条边的下一条边的索引。这种方式可以方便地遍历每个顶点的所有边。 链式前向星是一种基于链表的存储方式,它使用链表来存储每个顶点的边。每个顶点都有一个指向第一条边的指针,每条边都有一个指向下一条边的指针。这种方式可以动态地添加和删除边。 总结来说,前向星使用数组存储边的信息,链式前向星使用链表存储边的信息。链式前向星相比前向星更加灵活,可以方便地进行边的插入和删除操作。但是链式前向星的空间复杂度较高,因为需要额外的指针来存储链表的连接关系。 引用\[1\]提到,链式前向星的整体结构很像邻接表,但是实现方式不同。链式前向星的思想和邻接表一致,只是在实现上有所区别。因此,链式前向星的使用和邻接表相一致,可以用于存储和遍历图的边的信息。 #### 引用[.reference_title] - *1* *2* *3* [链式前向星](https://blog.csdn.net/MuShan_bit/article/details/123882339)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值