数据结构入门 — 链表详解_单链表

简介: 数据结构入门 — 单链表详解*系列文章第一篇:数据结构入门 — 链表详解_单链表第二篇:数据结构入门 — 链表详解_双向链表第三篇:数据结构入门 — 链表详解_循环链表

前言

数据结构入门 — 单链表详解*

关注博主,后期持续更新系列文章

*****感谢观看,希望对你有所帮助*****



系列文章

第一篇:数据结构入门 — 链表详解_单链表

第二篇:数据结构入门 — 链表详解_双向链表

第三篇:数据结构入门 — 链表详解_循环链表


文章目录

前言

系列文章

一、链表

1. 链表是什么

2. 优缺点

二、概念及结构

1. 概念

2. 结构

三、 链表的分类

1. 链表结构类型

2. 常用的两种链表结构

四、单链表接口实现(代码演示)

1. 动态申请一个结点

2. 单链表打印

3. 单链表增删查改

4. 单链表销毁

五、所有文件代码

1. Gitee链接

总结


一、链表


1. 链表是什么

链表是一种数据结构,由一系列节点组成,在每个节点中存储数据和指向下一个节点的指针。每个节点只包含指向下一个节点的指针,不像数组那样有预定义的大小。链表可以动态地增长和缩小,并且非常灵活,可以在任何位置插入或删除节点。链表主要分为单向链表、双向链表和循环链表等不同类型。


2. 优缺点

链表的优点:


  1. 灵活性:由于链表中每个节点都有指向下一个节点的指针,因此链表可以在任何位置添加或移除元素,使得链表非常灵活。
  2. 动态性:由于链表的大小不是固定的,当需要增加或删除元素时,内存中不需要重新分配空间,而是在链表中增加或删除一个结点。
  3. 无需占用连续的内存空间:相较于数组等数据结构,链表的每个元素之间并没有关联性,每个节点可以在内存中的任意位置,不需要占用连续的内存空间。


链表的缺点:


  1. 没有随机访问的能力:链表中的元素之间没有关联性,无法像数组那样通过下标直接访问某个元素,需要从头开始遍历整个链表才能找到需要的元素,这会导致链表的查找效率比数组低。
  2. 内存空间的额外开销:由于需要在每个节点中存储指向下一个节点的指针,链表内每个元素需要占用比其存储内容更多的内存空间,这会导致链表没有数组那么节省内存。
  3. 不支持常量时间内的随机访问:链表只能在头尾节点进行快速的插入和删除操作,但在其他位置插入和删除节点较为困难,需要先遍历找到要操作的位置,这会导致链表操作的时间复杂度较高。

二、概念及结构


1. 概念

链表是一种物理存储结构上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表

中的指针链接次序实现的。


2. 结构

在现实的数据结构中,链表的结构

image.png

注意:

  1. 从上图可看出,链式结构在逻辑上是连续的,但是在物理上不一定连续
  2. 现实中的结点一般都是从堆上申请出来的
  3. 从堆上申请的空间,是按照一定的策略来分配的,两次申请的空间可能连续,也可能不连续

三、 链表的分类


1. 链表结构类型

链表可以分为单链表、双向链表和循环链表三种类型。

image.png

除了这三种基本类型,还有一些派生的链表结构,如带有头节点的链表、带有尾指针的链表、带有哨兵节点的链表等。如下图有8种链表结构


1. 单向或者双向

image.png

2. 带头或者不带头(哨兵位)

image.png

3. 循环或者不循环

image.png

2. 常用的两种链表结构

无头单向非循环链表:

image.png

无头单向非循环链表:结构简单,一般不会单独用来存数据。实际中更多是作为其他数据结

构的子结构,如哈希桶、图的邻接表等等。另外这种结构在笔试面试中出现很多。

带头双向循环链表:

image.png

带头双向循环链表:结构最复杂,一般用在单独存储数据。实际中使用的链表数据结构,都

是带头双向循环链表。另外这个结构虽然结构复杂,但是使用代码实现以后会发现结构会带

来很多优势,实现反而简单了,后面我们代码实现了就知道了。


四、单链表接口实现(代码演示)

无头+单向+非循环链表增删查改实现


1. 动态申请一个结点

SLTNode*BuySListNode(SLTDataTypex)
{
SLTNode*newnode= (SLTNode*)malloc(sizeof(SLTNode));
if (newnode==NULL)
    {
perror("BuySListNode");
exit(-1);
    }
newnode->data=x;
newnode->next=NULL;
returnnewnode;
}

2. 单链表打印

voidSLTPrint(SLTNode*phead)
{
SLTNode*cur=phead;
while(cur)
    {
printf("%d->", cur->data);
cur=cur->next;
    }
printf("NULL\n");
}

3. 单链表增删查改

头插:

//头插voidSLTPushFront(SLTNode**pphead, SLTDataTypex)
{
assert(pphead);
SLTNode*newnode=BuySListNode(x);
newnode->next=*pphead;
*pphead=newnode;
}

尾插:

//尾插voidSLTPushBack(SLTNode**pphead, SLTDataTypex)
{
assert(pphead);
SLTNode*newnode=BuySListNode(x);
//如果为空 if (*pphead==NULL)
    {
*pphead=newnode;
    }
else    { 
SLTNode*tail=*pphead;
while (tail->next!=NULL)
        {
tail=tail->next;
        }
tail->next=newnode;
    }
}

头删:

//头删voidSLTPopFront(SLTNode**pphead)
{
//空assert(pphead);
assert(*pphead);
//非空SLTNode*newnode= (*pphead)->next;
free(*pphead);
*pphead=newnode;
}

尾删:

//尾删voidSLTPopBack(SLTNode**pphead)
{
assert(*pphead);
assert(pphead);
//一个节点if((*pphead)->next==NULL)
    {
free(*pphead);
*pphead=NULL;
    }
else    {
SLTNode*tail=*pphead;
SLTNode*tailPrev=NULL;
while(tail->next!=NULL)
        {
tailPrev=tail;
tail=tail->next;
        }
free(tail);
tail=NULL;
tailPrev->next=NULL;
    }
}

查找:

//查找SLTNode*SLTFind(SLTNode*phead, SLTDataTypex)
{
SLTNode*cur=phead;
while (cur)
    {
if (cur->data==x)
        {
returncur;
        }
cur=cur->next;
    }
returnNULL;
}

在pos之前插入x:

// 在pos之前插入xvoidSLTInsert(SLTNode**pphead, SLTNode*pos, SLTDataTypex)
{
assert(pos);
assert(pphead);
if (pos==*pphead)
    {
SLTPushFront(pphead,x);
    }
else    {
SLTNode*prev=*pphead;
while (prev->next!=pos)
        {
prev=prev->next;
        }
SLTNode*newnode=BuySListNode(x);
prev->next=newnode;
newnode->next=pos;
    }
}

在pos以后插入x:

// 在pos以后插入xvoidSLTInsertAfter(SLTNode*pos, SLTDataTypex)
{
assert(pos);
SLTNode*newnode=BuySListNode(x);
newnode->next=pos->next;
pos->next=newnode;
}

删除pos位置:

// 删除pos位置voidSLTErase(SLTNode**pphead, SLTNode*pos)
{
assert(pos);
assert(pphead);
if (pos==*pphead)
    {
SLTPopFront(pphead);
    }
else    {
SLTNode*tail=*pphead;
while (tail->next!=pos)
        {
tail=tail->next;
        }
tail->next=pos->next;
free(pos);
pos=NULL;
    }
}

删除pos的后一个位置:

// 删除pos的后一个位置voidSLTEraseAfter(SLTNode*pos)
{
assert(pos);
assert(pos->next);
SLTNode*posNext=pos->next;
pos->next=posNext->next;
pos->next=posNext->next;
free(posNext);
posNext=NULL;
}

4. 单链表销毁

voidDestory(SLTNode**pphead)
{
assert(pphead);
SLTNode*cur=*pphead;
while (cur)
    {
SLTNode*del=cur->next;
free(cur);
cur=del;
    }
*pphead==NULL;
}

五、所有文件代码


1. Gitee链接

***查看所有代码***

点击右边蓝色文字 DuckBro Gitee 代码仓库


总结

单链表的重点包括:


  1. 定义:单链表是一种数据结构,它由一系列节点组成,每个节点包含数据和指向下一个节点的指针。
  2. 插入操作:单链表的插入操作需要先找到要插入位置的前一个节点,然后将新节点插入到其后。
  3. 删除操作:单链表的删除操作需要先找到要删除的节点的前一个节点,然后将其指针指向下一个节点即可。
  4. 遍历操作:单链表需要从头节点开始依次遍历各个节点,获取其中存储的数据。
  5. 链表反转:单链表的反转操作是将链表中的节点从后往前连接,最后将原来的头节点变为尾节点。
  6. 快慢指针:快慢指针是单链表中常用的技巧,可以用于查找链表中的中间节点、判断是否有环等操作。
  7. 环形链表:有些单链表可能存在环形结构,即某个节点的指针指向之前的某个节点,使用快慢指针可以判断链表是否为环形。
  8. 链表排序:单链表可以使用排序算法进行排序,如冒泡排序、快速排序等。
  9. 链表的应用:单链表广泛应用于各种数据结构和算法中,如哈希表、图等。

如这篇博客对大家有帮助的话,希望 三连 支持一下 !!! 如果有错误感谢大佬的斧正 如有 其他见解发到评论区,一起学习 一起进步。

目录
相关文章
|
2月前
|
存储 算法 Perl
数据结构实验之链表
本实验旨在掌握线性表中元素的前驱、后续概念及链表的建立、插入、删除等算法,并分析时间复杂度,理解链表特点。实验内容包括循环链表应用(约瑟夫回环问题)、删除单链表中重复节点及双向循环链表的设计与实现。通过编程实践,加深对链表数据结构的理解和应用能力。
65 4
|
13天前
|
数据库
数据结构中二叉树,哈希表,顺序表,链表的比较补充
二叉搜索树,哈希表,顺序表,链表的特点的比较
数据结构中二叉树,哈希表,顺序表,链表的比较补充
|
2月前
|
存储 缓存 算法
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式,强调了合理选择数据结构的重要性,并通过案例分析展示了其在实际项目中的应用,旨在帮助读者提升编程能力。
74 5
|
2月前
|
算法
数据结构之购物车系统(链表和栈)
本文介绍了基于链表和栈的购物车系统的设计与实现。该系统通过命令行界面提供商品管理、购物车查看、结算等功能,支持用户便捷地管理购物清单。核心代码定义了商品、购物车商品节点和购物车的数据结构,并实现了添加、删除商品、查看购物车内容及结算等操作。算法分析显示,系统在处理小规模购物车时表现良好,但在大规模购物车操作下可能存在性能瓶颈。
55 0
|
2月前
|
C语言
【数据结构】双向带头循环链表(c语言)(附源码)
本文介绍了双向带头循环链表的概念和实现。双向带头循环链表具有三个关键点:双向、带头和循环。与单链表相比,它的头插、尾插、头删、尾删等操作的时间复杂度均为O(1),提高了运行效率。文章详细讲解了链表的结构定义、方法声明和实现,包括创建新节点、初始化、打印、判断是否为空、插入和删除节点等操作。最后提供了完整的代码示例。
80 0
|
8月前
【移除链表元素】LeetCode第203题讲解
【移除链表元素】LeetCode第203题讲解
|
7月前
|
存储 SQL 算法
LeetCode力扣第114题:多种算法实现 将二叉树展开为链表
LeetCode力扣第114题:多种算法实现 将二叉树展开为链表
|
7月前
|
存储 SQL 算法
LeetCode 题目 86:分隔链表
LeetCode 题目 86:分隔链表
|
7月前
|
存储 算法 Java
【经典算法】Leetcode 141. 环形链表(Java/C/Python3实现含注释说明,Easy)
【经典算法】Leetcode 141. 环形链表(Java/C/Python3实现含注释说明,Easy)
66 2
|
8月前
<数据结构>五道LeetCode链表题分析.环形链表,反转链表,合并链表,找中间节点.
<数据结构>五道LeetCode链表题分析.环形链表,反转链表,合并链表,找中间节点
77 1

热门文章

最新文章