数据结构笔记 -01线性表

线性表的定义

结构:

1. 线性结构: 结构中的数据元素之间均满足线性关系(一对一)。

图片.png

2. 由若干个数据项组成的数据元素,称为记录;含有大量记录的线性表称为文件;同一线性表中的元素必须属于同一对象。
3. 线性表:n个数据元素的有限序列 数据元素/结点:原子类型或结构类型 线性表长度:线性表中元素个数n 位序:各线性元素都有一个确定的位置,即位序
非空线性表通常记作:(a1,a2,……a i,a i+1,……a n),a1:开始结点、表头结点,a n:终止结点、表尾节点

抽象数据操作:

1. 线性表的抽象数据类型定义-创建删除:

图片.png

DestroyList(&L):释放掉表中的存储空间;ClearList(&L):将线性表恢复到空表状态,未释放存储空间。
2. 线性表的抽象数据类型定义-查找:
图片.png

ps:LocateElem:用指针的目的是提高操作的通用性
3. 组合的复杂操作:
①两线性表的合并
图片.png

图片.png

当找到与e相同的,则返回满足equal()关系的元素的位序,否则返回0。
算法实现:
图片.png

②归并有序线性表
图片.png

算法思路:先比较A、B两线性表中的第一个元素,将较小的那一个取出放入新线性表C;再比较A、B两线性表的元素,将较小的那一个取出放入新线性表C;重复此操作,直至A或者B的元素个数为0了,将剩下的表里面的元素全部插至C的末尾。
图片.png

算法实现:
图片.png

ps:线性表中的元素有序排列,可提高归并算法的时间效率。

顺序表

顺序表的存储结构

1. 线性表的顺序表示:把线性表的结点按逻辑顺序依次存放在一组地址连续的存储单元里。
2. 存储结构:只要知道了线性表中第一个元素的存储位置(基地址),那么线性表中任意一个元素,如第i个元素即可根据式子计算。

图片.png

3. 线性表的动态分配线性存储:顺序表SqList类型是结构体类型,由三个域组成。Elem指针域用来指示顺序表的基地址;length域用来存储当前表长;listsize用来存储线性表当前最大存储容量。(length域和listsize以元素个数为单位)
图片.png

顺序表基本操作的实现

1. 创建空线性表
算法思路:先分配一块存储空间;让Elem指针域指向它的基地址;将length域的值置为0

图片.png

算法实现:
图片.png

函数返回值Status类型是Int类型的别名,可以用OVERFLOW、OK等常量来代表函数执行结果的不同状态
2. 顺序表的插入
ListInsert将在第i个元素和第i-1个元素之间插入新元素;为防止元素被覆盖,元素搬动顺序应为由后往前搬动,如图。
图片.png

注意:
图片.png

算法实现:
realloc:按新的容量分配新的存储空间,并将原来空间里的数据拷贝到新的空间里,释放掉原来的空间。
若空间分配成功,相应地修改基地址指针域L.elem和存储容量域L.listsize
图片.png

3. 顺序表的删除
图片.png

注意:
图片.png

算法实现:
图片.png

4. 插入和删除操作的算法分析
最好和最坏情况下时间复杂度的分析:
图片.png

平均情况下移动元素次数的期望:
图片.png

总结:顺序表的插入和删除操作的时间复杂度都是O(n);缺点:在平均情况下,需要移动的表中元素为表中元素的一半,当顺序表长n很大时,耗费较大。
5. 顺序表的查找
按位序查找(GetElem):时间复杂度O(1)
按内容查找(LocateElem):从顺序表的第一个元素逐一比较
图片.png

ps:*(p++)指先比较p指向的元素和e的大小,再将p++;时间复杂度为O(n)。
6. 归并有序的顺序表
算法实现:
图片.png

ps:加入红色部分则实现并集操作
7. 顺序表的优缺点
图片.png

线性链表

线性表(链表)的链式存储

1. 链表的链式存储结构: 用一组任意的(可连续、也可不连续)存储单元来存储线性表的数据元素。
节点包含两种信息域:1)数据域:存储数据元素的信息 2)指针域:存储数据间的逻辑链接信息
2. 分类
按连接方式分类

  • 线性链表(单链表)
  • 循环链表
  • 双向链表
    按实现方式分类
  • 静态链表
  • 动态链表

线性链表

线性链表的动态链式存储:单链表

1. 结构特点: 链表中每个节点只包含一个用来指示直接后继的指针域。(如老鹰捉小鸡的小鸡)
2. 头指针: 用来指示链表第一个结点的存储位置

  1. 最后一个结点的指针域为NULL


    图片.png

    图片.png
  2. 假设L为单链表的头指针,则L应为LinkList型变量。当L=NULL时,该链表为空表
  3. 头结点:在表的第一个结点之前附设一个结点,其next域指向第一个元素结点,其data域可以不储存任何信息,也可以用于储存表长等附加信息。带头结点的单链表中,当头结点的next域为空时,该链表为空表
  4. 带头结点vs不带头结点:
  • 不带头结点的单链表:执行添加操作时,若添加的结点在第一个节点之前,则需要修改头指针;执行删除操作时亦是如此。
  • 带头结点的单链表
    ①单链表的查找(按位序查找):在单链表中,要读取第i个数据元素,必须从头指针L出发,先找到表中的第一个结点;再顺藤摸瓜,依次查找。
    具体操作:
    图片.png
    该操作的时间复杂度为O(n),在顺序表中只需要O(1)。
    ②单链表的插入:如果要将新元素e插入到第i个元素之前,则首先需要找到表中的第i-1个结点,然后把辅助指针p指在第i-1个结点上;若需要插入在第一个结点之前,则只需把p指在头结点上。
    具体操作:动态分配一个新节点,用s指针指向这个新结点;将新元素e写入这个结点;修改新结点的next指针域,让它指向表中第i个结点;修改p的next指针域,使它指向新插入的那个结点。
    图片.png
    顺序不能替换
    语言描述:
    图片.png

    ③单链表的删除:如果要删除第i个元素,则先将辅助指针p定位到第i-1个结点上,即被删除结点的直接前驱;此外,还需要引入一个辅助指针q用来指向被删结点;然后,修改第i-1结点的next指针,使其指向被删结点的直接后继;再将被删结点的值赋值给引用参数e;最后,释放掉被删结点,即q所指的结点。
    图片.png

    ?是否可以不引入辅助指针q:若不引入,则被删结点无法被free掉,它将成为系统中的太空垃圾,一直占用着这部分的存储空间,直到程序运行结束才会被释放,可能造成内存泄露的隐患。
    具体操作:
    图片.png

    ④单链表的创建:链式存储结构与顺序存储结构的最大区别在于,它是动态结构,链表所需的空间不必提前估算并分配,只需要按需实时动态分配或释放即可。因此,建立单链表的过程即是从空链表开始,依次生成各个结点,并逐个插入到链表的过程。
    具体操作:
    (1)该算法建立的是从表尾到表头逆向建立单链表
    图片.png

    (2)建立的是从表头到表尾正向建立单链表
    首先,增设一个表尾指针T,初始令其指向头结点;其次,将插入的位置改为插入到表尾节点之后;在每次插入后,修改T指针,使其每次指向新插入的那个结点。
    图片.png

    ⑤归并俩有序单链表:拆东墙补西墙,没有分配任何其他的结点空间,而是将原来的单链表重新分解开,按照数值大小连接成新的单链表。
    图片.png
线性链表的静态链式存储:静态链表

1. 定义: 在实际开发中,可能会遇到不方便使用指针或动态分配的情况,比如没有提供指针类型的编程语言,此时,可以采用一维数组来描述链表,这种实现的方法称为静态链表。
2. 结构特点: 预先分配一个较大的数组空间,数组中的元素有俩域,data域用来存储结点的数据,cur域称为游标或指示器,用来存储后继结点在数组中的下标。

图片.png

游标cur用结点在数组中的相对位置来代替结点在内存中的绝对位置(即指针),因此,静态链表中的元素存储位置可以是任意的,插入和删除时不需要移动元素,只需要修改游标;但缺点是,它与顺序表一样,需要提前分配一块存储空间,闲置的结点空间会杂乱地分布在数组中。
为了再利用这些空闲空间,可以利用cur域,将这些空闲的单元链接成一条备用链。
图片.png

因此,整个存储空间中有两条链表,一条是用来存储线性表的静态链表,另一条是空闲结点构成的备用链表。可以约定将数组下标为0的单元用作备用链表的头结点,另外设置变量S来存储链表的头指针。可以用cur域的值为0来表示该结点是表尾节点。
3. 带头结点的静态链表的操作
①按内容查找:根据cur域在表中顺链查找
图片.png

②初始创建静态链表:以space[0]作为头结点
图片.png

③插入结点时:若备用链表第一个结点非空,则删除备用链表的第一个结点,将其下标返回给插入算法,并将其作为待插入的新结点;反之,若备用链表已空(space[0].cur==0),则返回的是0,表示分配空间失败。
图片.png

④静态表中free的实现,即就是将被删掉的结点回收入备用链表:将被删结点插回备用链表表头,即插入在头结点space[0]之后。
图片.png

4. 静态链表的优缺点
兼具顺序存储和链式存储的部分特点,主要为不支持指针类型的编程语言提供了实现线性链表的方法。

  • 优点:插入和删除操作时,只需要修改游标,不需要移动元素。
  • 缺点:和顺序表一样,需要提前分配大块连续存储空间,无法解决难以确定合适存储规模的问题;失去顺序存储结构随机存取的优势,只能顺序存取。
实例

1. 集合运算的实现

图片.png

思路:1)先依次输入集合A中的各个元素,正序建立表示集合A 的静态链表S,并且用辅助指针r指向集合A中的最后一个结点;而后,每输入一个集合B的元素,b j+1(j的取值从0开始)。 2)在链表S中进行查找,最多查找到指针为r的结点即可。 3)如果存在与b j+1相同的结点,则从S中删除这个结点,否则,就把b j+1插入到r所指的结点之后。(集合B逆序排列在r所指结点之后)
图片.png

图片.png

图片.png

循环链表和双向链表

循环链表

1. 导言: 在实际生活中,我们往往需要遍历线性表,即需要逐一对表中的某结点做一些操作。
若我们需要按一定规律,逐一对线性表中的各个结点进行某种操作(称为访问),使得某个结点均被且只被访问一次。而该种操作用单链表实现,则只能从头指针开始。
2. 循环链表定义: 表中最后一个结点的指针域指向头结点,整个链表形成一个环。
3. 特点: 从表中的任意一个结点出发,都能遍历所有结点。与线性链表操作基本一致,差别在于算法中的循环终止条件不是“p或p->next为空”,而是他们是否等于头指针或起点。
4. 与单链表的区别:
在单链表中,如果只设置头指针,访问表头结点,仅需要O(1)时间,但访问表尾结点,则需要O(n)时间,若要提高表尾结点的访问效率,就得增设尾指针。
而对于循环链表中,设置尾指针而不设置头指针,就可以做到访问表头和表尾结点都只需要O(1)时间。
5. 两线性链表的头尾相接(合并): 当需要做到两线性链表头尾相接,合并成一个表时,采用循环链表结构,只需要修改两个指针值,仅需要O(1)时间。
具体操作:1)先设置两个辅助指针p和q,分别指向俩循环链表的头结点; 2)修改表A的表尾结点指针,使其指向表B的表头结点; 3)修改表B的表尾结点指针,使其指向表A的头结点; 4)释放掉表B的头结点。

图片.png

双向链表

1. 导言: 由于单链表只有一个指向后继结点的指针的特点,若用单链表找直接后继仅需O(1)的时间,但要找直接前驱,则需O(n)的时间。为解决这个麻烦,诞生了双向链表,在双向链表中,NextElem和PriorElem都仅需O(1)时间。
2. 双向链表定义: 链表的每个结点有两个指针域,一个指向直接后继,另一个指向直接前驱。(即小盆友手牵手排成一列)
3. 类型定义: 在单链表的基础上多了一个用来指向直接前驱的prior指针域。
4. 存储结构:

图片.png

5. 带头结点的双向循环链表:
图片.png

这样,循环链表就同时具有了两个方向的环路。当双向循环链表为空时,只有一个头结点,且头结点的next和prior都指向自己。
6. 带头结点的双向循环链表的操作
①ListLength、GetElem和LocateElem只需要涉及一个方向的指针,和单链表一致。
②插入:将指针s所指的新结点插入到p指向的结点之前,无需引入其他的指针。
具体操作:1)令要插入的那个新结点的s指针的前驱指向p指向结点的前驱 2)令p指向的结点的前驱结点的next指针指向新结点 3)令新结点的next指针指向p所指的结点 4)令p所指向结点的prior指针指向新结点
图片.png

?这四个步骤的顺序可以任意调换吗? 答:步骤四不能早于步骤一
具体算法实现:
图片.png

③删除:删除p指向的结点,也无需引入辅助指针。
具体操作:1)使目标结点的前驱结点的next指针指向目标结点的后继 2)令目标结点的后继结点的prior指针指向目标结点的前驱 3)释放掉目标删除结点
图片.png

顺序可对换
具体算法实现:
图片.png

顺序表与链表的比较

(图片为网络课程自截,侵删)

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

推荐阅读更多精彩内容

  • 转自:http://blog.csdn.net/oreo_go/article/details/52116214 ...
    YYT1992阅读 974评论 0 4
  • 大学的时候不好好学习,老师在讲台上讲课,自己在以为老师看不到的座位看小说,现在用到了老师讲的知识,只能自己看书查资...
    和珏猫阅读 1,443评论 1 3
  • 在上一篇文章中我们简单说了数据结构的概念和数据结构与算法的一些关系,这一篇文章的内容是关于线性表的东西,主要有线性...
    硅谷小虾米阅读 1,269评论 1 3
  • 1.线性表的定义 线性表:零个或多个数据元素的有限序列序列:也就是说元素之间是有顺序的,若元素存在多个,则第一个元...
    e40c669177be阅读 2,058评论 6 15
  • 今年的冬天真的很享受,来攀枝花半个多月了,每天都很暖和,只有一天下了点雨。后来通过出租车司机得知,那次下雨竟然是人...
    满鑫欢喜88阅读 257评论 2 3