数据结构与算法: 链表

使用数组包含以下限制:
线性表(数组):可以随机存储,存储密度高.但是要求连续空间,改变容量不方便.

在程序中使用之前,必须事先知道数组的大小。
增加阵列的大小是一个耗时的过程。在运行时扩展数组的大小几乎是不可能的。
数组中的所有元素都需要连续存储在内存中。在数组中插入任何元素都需要移动其所有前置元素。
链表是可以克服数组的所有限制的数据结构。使用链表很有用,因为,它动态分配内存。链表的所有节点都非连续地存储在内存中,并在指针的帮助下链接在一起。
大小不再是问题,因为我们不需要在声明时定义其大小。列表根据程序的需求增长,并限制为可用的内存空间。

头结点、头指针和首元结点

头结点

有时,在链表的第一个结点之前会额外增设一个结点,结点的数据域一般不存放数据(有些情况下也可以存放链表的长度等信息),此结点被称为头结点。

若头结点的指针域为空(NULL),表明链表是空表。头结点对于链表来说,不是必须的,在处理某些问题时,给链表添加头结点会使问题变得简单。

首元结点:链表中第一个元素所在的结点,它是头结点后边的第一个结点。

头指针:永远指向链表中第一个结点的位置(如果链表有头结点,头指针指向头结点;否则,头指针指向首元结点)。

头结点和头指针的区别

头指针是一个指针,头指针指向链表的头结点或者首元结点;头结点是一个实际存在的结点,它包含有数据域和指针域。两者在程序中的直接体现就是:头指针只声明而没有分配存储空间,头结点进行了声明并分配了一个结点的实际物理内存。
在这里插入图片描述
🎈注意:单链表中可以没有头结点,但是不能没有头指针。

链表:

单链表:不要求大片连续空间,改变容量方法,但是不可以随机存取,要耗费一定的空间存放指针

链表结构
在这里插入图片描述
在这里插入图片描述
本身的信息,称为“数据域”;
指向直接后继的指针 (next),称为“指针域”。

//定义结点类型
typedef struct Node {
    int data; //数据类型
    struct Node *next; //单链表的指针域
} Node,*LinkedList;  
//Node表示结点的类型,LinkedList表示指向Node结点类型的指针类型
typedef struct Link{
    char elem;//代表数据域
    struct Link * next;//代表指针域,指向直接后继元素
}link;
  • 链表可以定义为随机存储在内存中的称为节点的对象的集合。
  • 节点包含两个字段,即存储在该特定地址的数据和包含内存中下一个节点地址的指针。
    在这里插入图片描述

列表的最后一个节点包含指向 null 的指针。

  • 链表不需要连续存在于内存中。节点可以驻留在内存中的任何位置,并链接在一起以形成列表。这实现了空间的优化利用。
  • 列表大小限制为内存大小,不需要提前声明。
  • 空节点不能存在于链接列表中。
  • 我们可以将基元类型或对象的值存储在单个链接列表中。

其他链表

在这里插入图片描述

单向链表

单链表可以定义为有序元素集的集合。元素的数量可能会根据程序的需要而有所不同。单链接列表中的节点由两部分组成:数据部分和链接部分。节点的数据部分存储将由节点表示的实际信息,而节点的链接部分存储其直接后继者的地址。

单向链或单向链只能沿一个方向遍历。换句话说,我们可以说每个节点只包含下一个指针,因此我们不能以相反的方向遍历列表。
在这里插入图片描述

DS 单链接列表
在上图中,箭头表示链接。每个节点的数据部分都包含学生在不同科目中获得的分数。列表中的最后一个节点由空指针标识,空指针存在于最后一个节点的地址部分。我们可以在列表的数据部分拥有尽可能多的元素。

单向链表初始化(申请空间,指针初始化)

同任何的结构,类型一样,链表也需要初始化操作,初始化是创建一个单链表的前置节点并向后逐步添加节点,一般来说,我们所谓的初始化单链表一般指的是申请结点的空间,同时对一个结点辅以空值(NULL),其代码可以表示为:

LinkedList listinit(){
    Node *L;
    L=(Node*)malloc(sizeof(Node));      //开辟空间 
    if(L==NULL){ //判断是否开辟空间失败,这一步很有必要
        printf("申请空间失败");
        //exit(0); //开辟空间失败可以考虑直接结束程序
    }
    L->next=NULL; //指针指向空
}

在这里我们有一个注意点,就是一定要记住判断是否开辟空间失败,虽然在很多试题中以及常用的环境提供的环境非常安全,几乎没有开辟失败的存在,但是也一定要养成判断是否开辟失败并且判断失败后执行代码,但在生产中由于未知的情况造成一旦空间开辟失败任然在继续执行代码,后果将不堪设想,因此养成这样的判断是很有必要的,在C++中可以使用try-catch这样的语句进行优化。

双向链表

请添加图片描述
Node 创建

struct node   
{  
    struct node *prev;  
    int data;  
    struct node *next;  
};  
struct node *head;   

循环单链表

在这里插入图片描述
表头结点的prior指向NULL;
表尾结点的next指向NULL.

循环双链表

在这里插入图片描述

表头结点的prior指向表尾结点;
表尾结点的next指向头结点.

在数据结构中跳出链表

请添加图片描述
跳过列表中有以下类型的操作。

  • 插入操作:它用于在特定情况下将新节点添加到特定位置。
  • 删除操作:它用于在特定情况下删除节点。
  • 搜索操作:搜索操作用于搜索跳过列表中的特定节点。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Michael_chemic

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

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

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

打赏作者

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

抵扣说明:

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

余额充值