基本线性数据结构包括:线性表,栈和队列。
一、线性表
- 线性表中数据元素是一对一的关系
- 线性表的实现方法分为两种:数组和链表
1.数组实现线性表
数组是线性表的循序存储的实现方式,可以通过对数组的操作实现对线性表的各种操作。数组的主要操作有:值查询(search)、前端插入(push_front)、后端插入(push_back)、节点删除(delete)、下标查找(find)和插入(Insert)。
-
值查询:数组查找操作需要对数组进行遍历,最坏情况的时间复杂度为O(n),其中n为数组大小。在数组L中查找关键字为k的元素,存在则返回关键字为k的元素的下标,不存在则返回-1.
-
前端插入:在数组L的前端插入给定元素,若插入元素数超出数组大小则返回-1,表示插入失败;否则返回0.在数组前端插入元素x,需要把数组中其他元素向后移动一个位置,然后再在数组前端插入这个元素x,时间复杂度为O(n)。
-
后端插入:在数组后端插入元素,只需在线性表的后端添加元素即可,所以时间复杂度为O(1)。
-
节点删除:将下标为x的元素从数组l中删除。在数组中删除元素,需要把该下标指向位置之后的其他元素向前移动一个位置,同时修改数组中元素总数。最坏的时间复杂度为O(n)。
-
下标查找:返回数组L的第x个元素,直接返回对应位置的元素值,时间复杂度为O(1)。
-
插入: 在数组L的第k个元素后插入给定的元素x,若插入元素怒超过数组大小或者数组的元素个数少于k,则返回-1,表示插入失败;否则返回0。然后需要把数组中第k个元素之后的其他元素向后移动一位,在数组的第k+1个位置处插入这个元素x。最坏情况的时间复杂度为O(n)。
2.链表实现线性表
与数组方式不同的是,链表中的元素在内存中并不是连续存储的,而是通过当前元素包含下一个元素位置的方式指明元素间的顺序关系。链表为动态集合提供了一种实现方式。链表包含单向链表和双向链表。单向链表中的每个元素包含所需存储的位置和下一个元素的位置。双向链表的每个元素还多包含了前一元素的位置。
链表的主要操作有:值查询(search)、查找第x个元素(AT)、前端插入(push_front)、节点删除(delete)和插入(Insert)。
- 值查询:链表的存储顺序为乱序的,所以链表的值查询操作需要遍历整个链表,指导发现需要查询的值为止。最坏的情况需要对整个链表进行遍历,所以时间复杂度为O(n)。
- 查找元素:找到链表L的第x个元素,并返回节点的下标,如果不存在则返回-1.链表查找元素需要遍历整个链表找到并查询该元素,最坏的时间复杂度为O(n)。
- 前端插入:链表l的最前面插入关键字为x的新节点,插入成功返回true,失败返回false,时间复杂度为O(1)。
- 节点删除:删除链表L中元素下标为x的节点,需要在链表下标为x的节点和下标为x节点的后继节点的信息作出部分修改,链表节点删除的时间复杂度为O(1)。
- 插入:同删除,时间复杂度为O(1)。
3.栈(stack)
- 栈按照后进先出的原则存储数据,先进入的数据被压入栈底,最后的数据在栈顶,需要读取数据的时候从栈顶开始弹出数据。
- 栈是一种只能在一段进行插入和删除操作的数据结构。
- 栈的插入操作成为入栈,删除操作成为出栈。
- 栈可以用数组实现,使用一个整型变量记录栈顶位置,stack有两个变量:数组变量(array)表示栈,整型变量(top)指向入栈元素位置。stack.array[0]为栈底元素,stack.array[stack.top]为栈顶元素。
- 当 stack.top = -1时表示空栈
- 栈的主要操作有:判断空栈(empty)、栈大小(size)、入栈(Push)、出栈(pop)。
4.队列(queue)
- 队列是一种先进先出的数据结构,只允许在队列的前端删除数据、末端添加数据。
- 在队列中被删除的总是在集合中存在时间最长的元素。
- 队列有队尾和队头,队尾指向进入队列的新元素,也就是队列添加数据的一端,队头指向队列集合中存在时间最长的元素,也就是队列删除数据的一端。
- 队列的插入操作成为入队,删除操作称为出队。可以把出入队列看出成收银台排队等待结账的顾客,新来结账的顾客从队尾进入队列,完成结账的顾客从队头离开队列。
- 用数组实现队列,queue有三个变量:数组变量(array)表示队列,整型变量(head)表示队头位置,整型变量(tail)表示队尾位置。
- 队列的主要操作有:判断空队列(empty)、获取队列大小(size)、入队(push)、出队(pop)。
- 队列的时间复杂度都是O(1),空间复杂度为O(n)。
- 循环队列:从队列的操作可以看到,向队列中插入一些元素之后,从队头删除元素,这时空出来的位置不会被再次利用,造成内存空间的浪费。为了防止内存空间的浪费,当发现队尾达到数组尾部时就把队尾指针指向数组的头部,避免出队过多对内存的浪费,这种队列称为循环队列。循环队列判断空队列的方法有所不同,当循环队列为空队列或满队列时,由于队头位置是在队尾位置后面,所以需要增加一个变量记录队列中的元素个数。元素个数为0即为空队列,等于数组元素个数则为满队列。