线性表定义:
作为常见的一种数据结构,线性表是由0个或者多个数据元素组成的有限序列。
![](https://img.haomeiwen.com/i1751468/d84bdff6701ceeda.png)
a1无前驱元素,a1是a2的前驱元素,a2是a1的后继元素,an无后继元素;
当n=0时候,称为空表。
线性表操作:
-
InitList(*L)
:初始化并建立一个空的线性表 -
ListEmpty(*L)
: 判断线性表是否为空表 -
ClearList(*L)
: 将线性表清空 -
GetElem(*L, i, *e)
: 将线性表L中的第i个位置的元素返回给e -
LocateElem(* L,*e)
:在线性表L中查找与给定值e相等的元素,查找成功,则返回该元素的序号,否则返回0表示失败 ListInsert(*L, i, *e)
ListDelete(*L, i, *e)
-
ListLength(*L)
:返回线性表元素个数
1.线性表的顺序存储结构:
在读取数据时,不论是哪个位置,时间复杂度都是O(1);
而在插入和删除的时候,最好情况,即插入或者删除刚好是最后一个数据的时候,复杂度是O(1),最坏情况,即插入或者删除刚好是第一个数据的时候,事件复杂度是O(n),平均时间复杂度是O((n-1)/2),也就是O(n)。
综上:
线性表的顺序存储结构。适合元素个数比较稳定,不经常插入或者删除元素,更多的是读取数据的应用场景。
优点:
- 无须为表示表中元素之间的逻辑关系而增加额外的存储空间。
- 可以快速地存取表中任意位置的元素。
缺点:
- 插入和删除操作需要移动大量元素。
- 当线性表长度变化较大时,难以确定存储空间的容量。
- 容易造成存储空间的“碎片”。
2.线性表的链式存储结构:
线性表的链式存储结构的特点是用一组任意的存储单元存储线性表的数据元素,这组存储单元可以存在内存中未被占用的任意位置。
比起顺序存储结构每个数据元素只需要存储一个位置就可以了。现在链式存储结构中,除了要存储数据元素信息外,还要存储它的后继元素的存储地址(指针)。
也就是说除了存储其本身的信息外,还需存储一个指示其直接后继的存储位置的信息
我们把存储数据元素信息的域称为数据域,把存储直接后继位置的域称为指针域。指针域中存储的信息称为指针或链。这两部分信息组成数据元素称为存储映像,称为结点(Node)。
![](https://img.haomeiwen.com/i1751468/cd6217cab954fed2.png)
n个结点链接成一个链表,即为线性表(a1, a2, a3, …, an)的链式存储结构。
因为此链表的每个结点中只包含一个指针域,所以叫做单链表。
我们把链表中的第一个结点的存储位置叫做头指针,最后一个结点指针为空(NULL)。
头指针:
- 头指针是指链表指向第一个结点的指针,若链表有头结点,则是指向头结点的指针。
- 头指针具有标识作用,所以常用头指针冠以链表的名字(指针变量的名字)。
- 无论链表是否为空,头指针均不为空。
- 头指针是链表的必要元素。
头结点:
- 头结点是为了操作的统一和方便而设立的,放在第一个元素的结点之前,其数据域一般无意义(但也可以用来存放链表的长度)。
- 有了头结点,对在第一元素结点前插入结点和删除第一结点起操作与其它结点的操作就统一了。
- 头结点不一定是链表的必须要素。
![](https://img.haomeiwen.com/i1751468/dab98c42cf640e95.png)
![](https://img.haomeiwen.com/i1751468/e2b312275954bf5a.png)
如果没有头结点,则头指针直接指向NULL
单链表的插入:
![](https://img.haomeiwen.com/i1751468/5921212aaaee627b.png)
单链表的删除:
![](https://img.haomeiwen.com/i1751468/6618d6e50935a5a7.png)
单链表的数据插入和删除,时间复杂度都是O(n),但是如果在某个位置插入多个数据,顺序链表每次操作复杂度都是O(n),而单链表除了第一次操作为O(n)外,后面操作复杂度都是O(1)
综上:对于插入或者删除数据频繁的操作,单链表的效率就很明显了
网友评论