数据结构之单链表

一、什么是单链表

       链表由一系列的节点组成,是通过节点的指针链接次序进行存储数据的一种数据结构。

       和顺序表一样,链表也是线性表的一种。我们同样可以通过链表来实现通讯录项目的实现。链表分为单链表和双链表,今天我们主要学习单链表。

       在逻辑结构上顺序表和链表都是连续的,但在物理结构上顺序表是连续的而链表是非连续的。

       前文我们使用顺序表实现了通讯录项目,让我们仔细思考一下是否存在一些问题呢?比如多次的插入删除会导致程序运行效率低下,同时realloc动态增容的不确定性会导致空间浪费。而链表是一个个独立的存储空间从而避免这些问题。下面我们为进行单链表的实现。

二、单链表的初始化和打印

       定义两个变量:存储的数据(SLTDataType data)和指向下一个节点的指针(strcut SListNode* node)。

       这里通过typedef重命名int(SLTDataType),结构体SListNode(SLTNode)。用malloc创建节点空间,通过指针将节点连接起来,记住将最后一个指针置为NULL。

       创建SLTNode* plist变量以便于接下来实参传递。

三、单链表功能的实现

       所需功能实现的函数

       提前说明:plist是test.c文件中定义的结构体变量实参,pphead是SList.h和SList.c的形参,pcur是为了防止pphead位置改变的变量。

       假如尾插的是空链表,形参phead的改变(0变为NULL)不会形象实参plist的改变(仍为0),需要&plist(传一级指针的地址)。

       在实现函数功能之前我们需要区分*plist plist &plist

       第一个节点                                   *plist      **pphead
       指向第一个节点的指针                   plist       *pphead
       指向第一个节点的指针的地址      &plist        pphead

1.尾插及空间申请

       封装申请空间函数SLTBuyNode(x),定义新变量newnode,后用malloc申请空间,成功后及时将newnode -> next置为空。

       这里先assert(pphead)不能对空指针解引用,但链表可以为空。调用SLTBuyNode(x)函数,判断指针是否为空,空perror,非空定义SLTNode* ptail = *pphead从头节点开始遍历直到遇见NULL

2.头插

       assert(pphead)创建newnode变量申请空间后新节点指向原第一个节点,指向原第一个节点的指针指向新节点。

3.尾删

       assert(pphead&&*pphead)不能是空链表,不然删谁。假如链表只有一个节点直接free(),若链表有多个节点就创建两个变量prev和ptail,让prev=ptail,ptail=ptail->next,直到ptail->next为空时再free(ptail)。

4.头删

       和尾删类似,不过只删一个节点。

5.查找

       创建pcur方便后续的更改,不会改变pphead的地址。

6.指定位置插入数据

       assert(pphead&&*pphead&&pos),所传位置指针也不能为空。如果pos=*pphead,直接头插反之用prev指针的next找到pos,形成prev->newnode->(pos)的指针传递顺序。

7.指定位置之后插入数据

       assert(pos).这里有两种方法:法一:pos -> next = newnode; newnode -> next = pos -> next;
法二:newnode -> next = pos -> next; pos -> next = newnode;只能选法二,因为先pos -> next = newnode;会使得原pos -> next地址丢失或者定义一个next指针保存原pos -> next的地址再用法一

8.指定位置删除数据

       判断pos==*pphead,是即头删,否则就需要前置节点和后置节点,形成(prve -> next) -> (pos -> next)的指针传递顺序。

9.指定位置之后删除数据       

       assert(pos&&pos->next),借助del变量=pos->next,形成pos -> del ->(del->next)的指针传递顺序,free(del)。

       注意:*(解引用)的优先级低于->(结构体指针访问操作符),同时使用要带()。

四、单链表的销毁

       链表不能为空并且指向链表的指针也不能为空。assert(pphead&&*pphead)。通过循环指向下一个节点的指针置为空并不断的释放下一个节点。注意:头节点被释放要及时置为空,否则就是野指针。

五、完整代码

SList.h

SList.c

test.c

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值