链表操作

1. 链表概述

	链表是一种物理存储单元上非连续, 非顺序的存储结构, 数据元素的逻辑顺序是通过链表中的指针链接
	次序实现的, 链表由一系列节点(链表中的每个元素称为节点)组成, 节点可在运行时动态生成. 

1.1. 链表与数组优缺点

   优点: 
   		1. 不需要于预先知道数据大小, 可以动态改变大小
   		2. 链表结构可以充分利用计算机内存空间, 灵活实现内存的动态管理.
        3. 常规数组排列关联项目的方式可能不同于这些数据项目在记忆体或磁盘上的顺序, 数据的存取
        往往要在不同的排列顺序中转换, 链表允许插入和移除链表上任意位置上的节点. 
   	缺点:
   	    1. 失去了随机读取的优点, 数组可以根据下标随机读取, 链表需要遍历, 效率低下.
   	    2.  链表增加了节点的指针域, 空间开销较大.  

1.2. 链表的分类

	根据存储方式不同可分为 线性表 和 非线性表.
	还可以根据遍历方式不同分为 单向链表, 双向链表, 循环链表.

2. 链表操作

	链表常用操作与数据库类似, 增, 删, 改, 查.
	此处以双向链表进行演示, 单向, 循环链表操作类似.

2.1. 链表定义

struct list_node
{
	struct list_node *next;   //指向后一个节点
	struct list_node *prev;   //指向前一个节点
};
typedef struct list_node list_t;

在这里插入图片描述

2.2. 链表初始化

void list_init(list_t *l)
{
	l->next = l->prev = l;
}

在这里插入图片描述

2.3. 链表插入节点

双向链表的插入分为 表头前插 和 表头后插. 
2.3.1. 表头前插
void list_insert_before(list_t *l, list_t *n)
{
	l->prev->next = n;   // Step1: 将表头节点的上一个节点指向的下一个节点修改为新节点.
	n->prev = l->prev;   // Step2: 将新节点的上一个节点修改为头节点的上一个节点.
	l->prev = n;         // Step3: 将头结点的上一个节点修改为要插入的新节点.
	n->next = l;         // Step4: 将新节点的下一个节点修改为头结点.
}

在这里插入图片描述

2.3.2. 表头后插
void list_insert_after(list_t *l, list_t *n)
{
	l->next->prev = n;    // Step1: 将表头节点的下一个节点的上一个节点修改为新节点.
	n->next = l->next;    // Step2: 将新节点的下一个节点修改为头节点的下一个节点.
	l->next = n;          // Step3: 将头结点的下一个节点修改为要插入的新节点.
	n->prev = l;          // Step4: 将新节点的上一个节点修改为头结点.
}

在这里插入图片描述

2.3.3. 节点删除
void list_remove(list_t *n)
{
	n->next->prev = n->prev;  // Step1: 将删除节点的下一个节点的上一个节点修改为删除节点的上一个节点.
	n->prev->next = n->next;  // Step2: 将删除节点的上一个节点的下一个节点修改为删除节点的下一个节点.
	n->next = n->prev = n;    // Step3:将删除节点的上一个节点和下一个节点修改为删除节点.
}

在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值