数据结构——线性表

290 阅读5分钟

定义与基本操作

数据结构三要素——逻辑结构、数据的运算、存储结构(物理结构)

线性表是具有相同数据类型的n(n≥0)个数据元素的有限 序列,其中n为表长,当n = 0时线性表是一个空表。若用L命名线性表,则其一般表示为 L=(a1,a2,,ai,ai+1,,an)L = (a_1, a_2, … , a_i, a_{i+1}, … , a_n)

ai是线性表中的“第i个”元素线性表中的位序 a1是表头元素;an是表尾元素。 除第一个元素外,每个元素有且仅有一个直接前驱;除最后一个元素外,每个元素有且仅有一个直接后继。

基本操作

InitList(&L):初始化表。构造一个空的线性表L,分配内存空间。 DestroyList(&L):销毁操作。销毁线性表,并释放线性表L所占用的内存空间。 ListInsert(&L,i,e):插入操作。在表L中的第i个位置上插入指定元素e。 ListDelete(&L,i,&e):删除操作。删除表L中第i个位置的元素,并用e返回删除元素的值。 LocateElem(L,e):按值查找操作。在表L中查找具有给定关键字值的元素。 GetElem(L,i):按位查找操作。获取表L中第i个位置的元素的值。 其他常用操作: Length(L):求表长。返回线性表L的长度,即L中数据元素的个数。 PrintList(L):输出操作。按前后顺序输出线性表L的所有元素值。 Empty(L):判空操作。若L为空表,则返回true,否则返回false。

顺序表的定义

顺序表―一用顺序存储的方式实现线性表顺序存储。把逻辑上相邻的元素存储在物理位置上也相邻的存储单元中,元素之间的关系由存储单元的邻接关系来体现。

静态分配代码定义

image-20230311100326338

动态分配及扩容代码

image-20230311100508425

思维导图

image-20230311093002488

顺序表的插入与删除

插入

image-20230311094502159

删除

image-20230311094530451

思维导图

image-20230311094602676

顺序表的查找

GetElem(L,i):按位查找操作。获取表L中第i个位置的元素的值。

LocateElem(L,e):按值查找操作。在表L中查找具有给定关键字值的元素。

思维导图:

image-20230311095717912

单链表的定义

image-20230311100008089

代码定义:

image-20230311100226131

结构体类型和指针类型的定义及使用:

image-20230311105633929

不带头节点的单链表

image-20230311110012880

带头节点的单链表

为了实现某些操作更加方便image-20230311152753984

思维导图

image-20230311153137385

单链表插入删除

带头节点按位序插入

ListInsert(&L,i,e):插入操作。在表L中的第i个位置上插入指定元素e。

image-20230311154058206

上述代码的时间复杂度很显然为O(n)O(n)

不带头节点按位序插入

不带头节点的话,如果插入的是第一个节点需要特判

image-20230311154947160

后插操作

image-20230311155307975

可以在前面的两个按位查找到元素后调用本方法。且对于单链表中节点p,其前的元素是未可知的,但其后的元素可逐渐遍历到。

前插操作

  1. 找到目标节点的前驱节点,在前驱节点之后进行插入操作即可(时间复杂度为O(n)O(n))。

  2. 但是有一种简单的方法(时间复杂度为O(1)O(1)),data的偷天换日(新插入的节点的值替换为为原节点的值,原节点的值替换为为新插入节点的值):

image-20230311155759856

带头节点的删除操作

ListDelete(&L,i,&e):删除操作。删除表L中第i个位置的元素,并用e返回删除元素的值。

image-20230311160424962

需要特殊处理,改变首元节点的指针L的指向。

删除指定节点

  1. 可以遍历找到前驱节点进行删除
  2. 也可以和前面在指定节点前插入节点一样,使用偷天换日的方法。即将指定节点的data域覆盖为其后继节点的data域;再将其next指向其后继节点的next。(指定结点是最 后一个结点时,需要特殊处理)
image-20230311161246479

思维导图

image-20230311161350028

单链表的查找

GetElem(L,i):按位查找操作。获取表L中第i个位置的元素的值。

LocateElem(L,e):按值查找操作。在表L中查找具有给定关键字值的元素。

带头节点的按位查找

image-20230311161951707

上面代码如果传入的是0,运行结果返回头节点;如果是不合法的次位,运行结果返回NULL

带头节点的按值查找

image-20230311163709458

单链表的长度

image-20230311163826802

思维导图

image-20230311163842921

单链表的建立

尾插法

每次对尾节点进行后插操作:

image-20230311164649432

头插法

每次对头节点进行后插操作(头插法可以实现链表的逆置)

image-20230311165113107

双链表

双链表的定义及其初始化

image-20230311170121371

双链表的插入

image-20230311170219357

双链表的删除

image-20230311170616361

双链表的遍历

image-20230311170915298

思维导图

image-20230311171058671

循环链表

循环单链表

从一个结点出发可以找到链表中任意结点

image-20230311171249161

image-20230311171451855

循环双链表

image-20230311171858421

此时,在双链表部分边界处不合法的两个操作(插入和删除)也变得合法了:

image-20230311171938761

image-20230311172052715

思维导图

image-20230311172137728

静态链表

静态链表:分配一整片连续的内存空间,各个结点集中安置(用数组的方式实现的链表)。

优点:增、删 操作不需要大量移动元素 缺点:不能随机存取,只能从头结点开始依次往后查找;容量固定不可变

适用场景:①不支持指针的低级语言;②数据元素数量固定不变的场景(如操作系统的文件分配表FAT)

image-20230315200729826

静态链表的定义

image-20230315200751308

等价定义

image-20230315200827625 image-20230315200856072

常用操作

image-20230315201041126