【数据结构】链表(LinkedList)

还是戒个好康欸、♪✧~~

感冒了....好难受....呜呜呜....|( ´・∧・`)

叒换了新头像,嘻嘻,看到的宝子,记得随手留下你的小心心哦 ~ 十分感谢哒啦~~


✨链表基础✨

链表是一种动态数据结构,通过指针连接各个节点。每个节点包含数据域和指针域。

节点定义:

typedef struct _node {
    int value; // 数据元素
    struct _node *next; // 指向下一个节点的指针
} ListNode;

✨链表操作✨

基本操作实现:

(1)创建链表:创建链表时,需要定义链表节点的结构,通常包含数据域和指针域。数据域用于存储数据,指针域用于存储指向下一个节点的地址。可以通过不断申请新节点并将其链接到已有节点的方式来构建链表。

(2)遍历链表:遍历链表是指按照链表中节点的链接关系,依次访问链表中的每个节点。遍历操作通常从链表的头节点开始,通过指针域访问下一个节点,直到访问到链表的末尾。

(3)插入节点:在链表中插入新节点时,需要调整节点之间的指针关系。例如,要在一个给定节点之前插入一个新节点,可以先将新节点的指针域指向给定节点,然后将给定节点的前一个节点的指针域指向新节点。

(4)删除节点:删除链表中的节点时,需要先找到待删除节点的前一个节点,然后将该前驱节点的指针域指向待删除节点的后继节点。这样,待删除节点就会从链表中分离出来,随后可以释放该节点占用的内存。

(5)查找节点:查找链表中的节点通常是基于节点的数据进行的。从链表的头节点开始,逐一比较每个节点的数据,直到找到匹配的节点或到达链表末尾。

(6)释放链表:释放链表涉及释放链表中每个节点占用的内存。可以从头节点开始,逐一访问每个节点并释放其占用的内存,直至到达链表末尾。

除了上述基本操作外,链表还支持其他操作,如修改节点数据、获取链表长度、清空链表等。链表的操作效率依赖于链表的结构和具体的操作实现。


✨链表类型✨

表格
类型优点缺点
单向链表简单,内存开销小只能单向遍历
双向链表可双向遍历,删除高效内存开销大
循环链表可循环访问需要小心循环引用

✨链表例题✨

约瑟夫问题

题目描述

$n$个人围成一圈,从第一个人开始报数,数到 $m$ 的人出列,再由下一个人重新从 $1$ 开始报数,数到 $m$的人再出圈,依次类推,直到所有的人都出圈,请输出依次出圈人的编号。

注意:本题和《深入浅出-基础篇》上例题的表述稍有不同。书上表述是给出淘汰 $n-1$ 名小朋友,而该题是全部出圈。

输入格式

输入两个整数 $n,m$

输出格式

输出一行 $n$ 个整数,按顺序输出每个出圈人的编号。

输入输出样例

输入:

10 3

输出:

3 6 9 2 7 1 8 5 10 4

说明/提示

$1 \le m, n \le 100$


这道题我是用链表结构做的,这题难度在于数到n时要把它弹出来,也就是把它删掉,这时候你就要重新连接前后结点,不然的话它就会变成野指针(就是结点间连接不上),具体操作在这里:

temp = p -> next;//用temp储存要删除的结点
p -> next = temp -> next;//注意!这步就是连接要删除的那个结点的上一个结点和要删除的那个结点的下一个结点,也可以写成 temp = p -> next - >next;
p = p -> next;//更新p 的结点
free(temp);//释放空间 

还有就是这个链表在读入完数据之后要将它的尾巴和头相连,具体实现如下

tail -> next = head -> next;

以此来构成循环链表

题解如下:

#include<iostream>
#include<cstdio>
#include<cstdlib>//用free()要用这个库
using namespace std;
int m, n;
struct Node{
	int data;
	Node *next;
} *head, *p, *tail, *temp;
int main(){
	scanf("%d%d",&m,&n);
	head = new Node;
	head -> next = NULL;
	tail = head;
	for(int i = 1; i <= m; i++){
		p = new Node;
		p -> data = i;
		p -> next = NULL;
		tail -> next = p;
		tail = p;
	}
	p = head -> next;
	tail -> next = head -> next;// 链接尾和头 
	for(int i = 1; i <= m; i++){
		for(int j = 1; j < n - 1; j++){
			p = p -> next;
		}
		printf("%d ",p -> next -> data);
		temp = p -> next;
		p -> next = temp -> next;//连接要删除那个结点上下结点
		p = p -> next;//更新
		free(temp);//释放空间 
	}
	return 0;
}

这个是洛谷P1996题,感兴趣的宝子可以去做一下

P1996 约瑟夫问题


表格
操作时间复杂度空间复杂度
访问O(n)O(1)
插入O(1)O(1)
删除 O(1)O(1)
查找O(n)O(1)

总结

链表适合频繁插入删除的场景,但不适合随机访问。掌握链表有助于理解更复杂的数据结构,在实际开发中应根据需求选择合适的链表类型。

如描述有误请在评论里告诉我,不然我怕》。。我搁着咕噜咕噜一顿叭叭,有错...也没人理我...

感谢您看到这里,点个三连~不过分叭(>ω・* )ノ

评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值