【数据结构】链表操作 的时间复杂度总结

文章目录

    • 1. 什么是链表?
    • 2. 常用链表操作
    • 3.操作的时间复杂度

1. 什么是链表?

链表(linked list) 是一种互相有联系的list结构,因为它每块空间里不仅存了元素对象(key),还存了指向前面或者后面一个元素的指针。

链表有多种形式。双链表有两个指针,next 和 prev, 分别指向后一个和前一个元素;单链表只有一个指向后面的指针。还有有序链表(sorted)、无序链表(unsorted)、循环链表(circular list) (head的prev指针指向tail,tail的next指针指向head)
单链表
【数据结构】链表操作 的时间复杂度总结_第1张图片
如图,单链表有head没有tail , 双链表有head和tail, 分别为第一个和最后一个元素。

2. 常用链表操作

list API 含义
PushFront(Key) 把key加到l链表最前面
Key TopFront() 返回第一个值
PopFront() 移除第一个值
PushBack(Key) 加到链表最后面
Key TopBack() 返回最后一个值
Key PopBack() 移除最后一个值
Boolean Find(Key) 判断key是否在链表中
Erase(Key) 移除key
Boolean Empty() 判断链表是否为空
AddBefore(Node, Key) 在node前面加key值

3.操作的时间复杂度

3.1. PushFront(Key) 最前面加一个元素
关键是修改指针:原head要有prev指针并指向新元素;新元素的next的指针要指向原head。新元素成为新的head, 要设其prev指针为空。

x.next = L.head
if L.head != NIL
	L.head.prev = x
L.head = x
x.prev = NIL

时间复杂度为O(1). 在最后面加一个元素方法类似,也为O(1).

3.2. Find(Key) 找一个链表中的元素
在数组中找到一个元素返回的是下标,链表中找到元素后返回的是指针,如果没找到就返回NIL.
想在链表L中找元素k,过程如下:
从头找,把链表的头赋给x, 判断x是否为空以及是否为k值,都不是就看下一个值,直到x为空或者找到k停止。

x = L.head
while x != NIL and x != k:
	x = x.next
return x

可以看到需要一个一个往后找,时间复杂度为O(n)

3.3 POPBACK() 移除最后一个值
对于最后一个值的操作,单双链表复杂度不同。
单链表只有head,需要一个一个往后找,直到找到最后一个元素(x.next = NIL), 才能进行移除操作,复杂度为O(n);
双链表有head和tail,直接操作,复杂度O(1)。
虽然双链表在最后一个值相关的操作上复杂度更低,但由于存储了两个指针, 所占内存大于单链表。

总体归纳如下

list API 单链表 双链表
PushFront(Key) O(1) -(same)
TopFront() O(1) -
PopFront() O(1) -
PushBack(Key) O(n) O(1)
TopBack() O(n) O(1)
PopBack() O(n) O(1)
Find(Key) O(n) -
Erase(Key) O(n) -
Empty() O(1) -
AddBefore(Node, Key) O(n) O(1)
AddAfter(Node, Key) O(1) -

参考资料:

  • 《Data-Structures》(coursera)
  • 《Introduction to algorithms -3rd》by Thomas H.Cormen, 10.2

你可能感兴趣的:(数据结构基础)