记录十一 线性表的链式存储结构

前言

在前面记录八 线性表的顺序存储结构记录九 线性表的顺序存储结构扩展(动态顺序表)中我们了解到线性表的顺序存储结构。我们能够了解到其顺序表的优缺点。我们知道,顺序表的查找和更新是十分快的。通过下标索引的话,其时间复杂度为常数阶。但是,我们在进行插入,删除的时候,我们发现,我们通常需要移动大量的数据才可以完成。有没有什么存储结构能够快速的插入和删除呢?
当然有,那就是链式存储结构

顺序表的链式存储结构

链式存储结构,又叫链接存储结构。在计算机中用一组任意的存储单元存储线性表的数据元素(这组存储单元可以是连续的,也可以是不连续的).【1】

链式存储结构的存储单元通常是不连续的,其每一个数据结点通常是由两个域组成。数据域指针域(我通常认为指针域为关系域,因为部分语言并没有指针。以下,我会将指针域改成关系域)。然后每一个数据结点进行连接。

数据域 :存放数据的地方。
关系域(指针域) :存放数据之间关系的地方。
其存储结构抽象类型为
ADT 链式存储结构{
    数据域:存放数据
    关系域(指针域):存放数据之间的关系
}结点;

那么数据之间是如何联系的呢?下看图:

举个栗子图

因为链式结构的对数据的关系是通过关系域(指针域)来联系的。所以存储空间不用连续。而因为每一个数据结点都增加了一个关系域(指针域),所以其在空间上会增加。

链表

链表,是其线性表的链式存储结构的简称。链表通常有:单链表、双向链表、循环链表、循环双向链表、静态链表,循环静态链表、循环静态双向链表等等。

单链表大致如下图(这个是我学链表的时候理解画的。偷一下懒)
结构体实现链表

掌握了单链表,除了静态链表之外,其它的都比较好理解。

单链表的方法

构造单链表

在构造单链表之前,我们首先要了解到一个概念:首元结点头结点

首元结点:带有数据的第一个结点。

头结点:首元结点的直接前驱结点,其没有直接前驱。

(带头结点的链表和不带头结点的链表)

首元结点和头结点

(为什么要带一个头结点呢?这不白白增加了空间吗?增加了空间不假,但是增加了头结点之后,可以增加其数据的操作性。也就是说。带头结点的链表比不带头结点的链表在插入和删除上更加方便!)

推荐博客:深刻理解:带头结点和不带头结点的区别 使用头结点的优势

所以,在构造单链表的时候,有两种方式:
1.构造带头结点的链表
2.构造不带头结点的链表

方法为(序号对应上面方式):
1.header -> data = new Node; header->next = NULL;(为头结点的数据域申请内存,关系域(指针域)赋值为空)
2.header = NULL;(没有头指针,我们在构造的时候没有数据,可以直接让header为空)

添加结点

添加结点也有两种方式:头插法尾插法

头插法:数据通过头指针直接添加到链表中。(头插法在遍历的时候,数据的顺序和插入时的顺序是相反的。例如,插入的顺序是1、2、3、4、5。则遍历输出后则就是5、4、3、2、1.)

尾插法:首先遍历找到尾部结点。然后通过尾部结点将数据添加到链表中。(其主要是麻烦在需要找到尾部结点。如果只有头指针,则每一次添加都需要遍历一次来链表。所以我们通常会添加一个尾指针来指向链表的尾部。)

方法为:
1.头插法:
1.添加的结点的关系域(指针域)先指向首元结点。(保存原先的数据)
2.再将头结点指向新添加的结点。(没有头结点,就直接让添加的结点变成头指针)

(带头结点的的链表)
newNode->next = header->next;//新添加的结点先保存好原先的数据。指向首元结点
header->next = newNode;//再将头结点的指针域指向新添加的结点。
(不带头结点的链表)
newNode->next = header;//先保存好原先的数据。即添加结点的关系域(指针域)指向首元结点
header = newNode;//修改头指针

2.尾插法:
1.先找到尾结点。
2.尾结点的指针域指向新添加的结点。

(没有尾结点的链表)
Node move = new Node;//创建一个移动的指针。(不能用头指针去寻找尾结点,因为头指针是整个链表的标识。如果我们找不到头结点的时候,我们就找不到链表了。)
//带有头结点的链表
while(move ->next != NULL){//循环找到尾结点
    move = move->next;
}
//不带头结点的链表
while(move != NULL){//循环找到尾结点
    move = move->next;
}
newNode->next = move->next;//先保存好尾部结点的指针域。(单链表尾结点为NULL)
move->next = newNode;//尾部结点指向新添加的数据。
(有尾结点的链表)
newNode->next = tail->next;//先保存好尾部结点的指针域
tail  = newNode;//尾部结点指向新的结点

插入数据

插入数据

方法:
1.找到需要插入结点的前一个结点。
2.将插入结点的指针域指向第一步找到结点的指针域。(保存数据,防止数据丢失)
3.将第一步找到的结点的指针域指向插入结点
(不需要移动大量的数据,只需要移动指针即可。)

(设需要将newNode结点插入到insertNode结点之前)
Node move = new Node;//创建一个移动的指针。(不能用头指针去寻找尾结点,因为头指针是整个链表的标识。如果我们找不到头结点的时候,我们就找不到链表了。)
//带有头结点的链表(没有头结点特别不好插入。各种判断。这里就不进行了。)
while(move->next != NULL){//循环遍历,查找的数据的前一个结点。
    if (move->next->data == insertNode->data){//查找到前一个结点
         break;         
    }
    move = move->next;
}
newNode->next = move ->next;//(move为插入结点的前一个结点.move->next指向的就是insertNode)
move->next = newNode;//插入新结点

删除数据

删除数据

方法:
1.找到需要删除结点的前一个结点。
2.保存第一步找到的结点的指针域。
3.将第一步找到的结点的指针域等于下一个结点的指针域。
3.释放第二步保存的指针域。

(设需要删除delNode结点)
Node move = new Node;//创建一个移动的指针。(不能用头指针去寻找尾结点,因为头指针是整个链表的标识。如果我们找不到头结点的时候,我们就找不到链表了。)
//带有头结点的链表
while(move->next != NULL){
      if(move->next->data == delNode->data){//第一步:判断是否为需要删除的结点(move是需要删除结点的前一个结点的)
              Node del = move->next;//第二步:保存需要删除的结点
              move->next = move->next->next;//第三步:删除结点
              delete del;//第四步:释放内存
              break;
      }
      move = move->next;
}

总结

链式存储结构使用与大量的插入和删除操作。其不适合与查找操作。因为其查找每次都的遍历整个链表。而且。链式存储结构会比顺序存储结构多一个空间。用来存放数据的关系。且链式存储结构不需要连续的空间。而顺序存储结构一定是连续的。

链式存储结构的抽象类已经在记录七 线性表给出。

参考资料:【1】百度百科-链式存储结构

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,294评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,493评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,790评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,595评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,718评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,906评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,053评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,797评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,250评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,570评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,711评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,388评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,018评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,796评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,023评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,461评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,595评论 2 350

推荐阅读更多精彩内容