【数据结构】单链表详解-无头单向不循环链表

1、前言

了解过顺序表的缺陷后,我们知道必要的优化在于:
1.按需申请释放;
2.不要挪动数据。
那么,链表又如何能做到真正的按需扩容?

2、链表简介

链表是一种物理存储上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的 。
表现形式:单链表、双链表和循环链表
主要特征:单向、双向、带头、不带头、循环、不循环
链表的八种结构:带头单向循环链表、带头单向非循环链表、带头双向循环链表、带头双向非循环链表、无头单向循环链表、无头单向非循环链表、无头双向循环链表、无头双向非循环链表

2.1组成

链表:由若干个同一结构类型的结点依次串联而成,每个结点保存下一个结点的地址。
结点:数据域和指针域。(结点类型为结构体,方便存储不同类型的数据和指针)
数据域:存储数据元素。
指针域:存储下一个结点的地址。

2.2逻辑结构

每个结点分为两个区域:数据域和指针域。(一般逻辑结构是现象出来便于理解学习的)

在这里插入图片描述

2.3物理结构

反映内存中结构的存储以及结点之间的关系。
在这里插入图片描述
与顺序表不同的是,内存地址完全是随机的,不一定相邻。

3、创建结构体

//创建单链表的结构体(即结点类型,包含组成链表的数据和指针)
typedef int DataType;

typedef struct ListNode
{
   
	DataType data;//数据域:存储数据
	struct ListNode* next;//指针域:存储下一个结点的地址
}LTNode;

4、链表接口

//接口
//创建结点
LTNode* BuyLTNode(DataType x);
//创建单链表(可以不写)
LTNode* CreatList(int n);
//打印
void LTPrint(LTNode* phead);
//尾插
void LTPushBack(LTNode** pphead, DataType x);//找尾
//尾删
void LTPopBack(LTNode* phead);
//头插
void LTPushFront(LTNode** pphead, DataType x);
//头删
void LTPopFront(LTNode** pphead);
//查找
LTNode* LTFind(LTNode* phead, DataType x);
//先find后insert/erase
//在pos结点之后插入数据
void LTInsertAfter(LTNode* pos, DataType x);
//pos结点之前插入数据
void LTInsert(LTNode** pphead, LTNode* pos, DataType x);
//删除pos结点之后的一个数据
void LTEraseAfter(LTNode* pos);
//删除pos结点位置数据
void LTErase(LTNode** pphead, LTNode* pos);
//销毁
void LTDestroy(LTNode** pphead);

为什么部分接口函数在实现时需要传递二级指针参数?

//测试
void test()
{
   
	DataType* plist = NULL;
}

这是因为实参作为一个一级指针指向内存空间地址,如果想对头结点进行操作,就需要使用二级指针将改变的数据传递回实参所在的函数内。另外,二级指针用在这个地方可以作为最优解(C语言)看待,摒弃了许多麻烦的操作。

5、创建结点

//创建结点
//由于
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

捌音

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值