链表(linked list)是这样一种数据结构,其中的各对象按线性顺序排列。数组的线性顺序是由数组下标决定的。然而与数组不同的是,链表的顺序是由各个对象里的指针决定的。
双向链表(doubly linked list)L的每个元素都是一个对象,每个对象有一个关键字key和两个指针:next和prev。对象中还可以包含其他的辅助数据。
设x为链表的一个元素,x.next指向它在链表中的后继元素,x.prev指向它的前驱元素。如果x.prev=NIL,则元素x没有前驱,因此是链表的第一个元素,即链表的头(head)
如果x.next=NIL,则元素x没有后继,因此是链表的最后一个元素,即链表的尾(tail)。属性L.head指向链表的第一个元素。如果L.head=NIL,则链表为空。
(1)链表的搜索(LIST-SEARCH(L,k))
采用简单的线性搜索方法,用于查找链表L中第一个关键字为k的元素,并返回指向该元素的指针。如果链表中没有关键字为k的对象,则该过程返回NIL.
最坏运行时间O(n)
(2)链表的插入(LIST-INSERT(L,x)):
给定一个已设置好关键字key的元素x,过程LIST-INSERT(L,x)将x连接入到链表的前端。
运行时间O(1)
(3)链表的删除(LIST-DELETE(x)):
过程LIST-DELETE(x)将一个元素从链表L中移除,该过程要求给定一个指向x的指针,然后通过修改一些指针,将x“删除出”链表。如果要删除具有给定关键字值的元素,则必须先调用LIST-SEARCH(L,k)找到该元素。
最坏运行时间O(n)
class DoublyNode:
def __init__(self,n_prev,n_next,key):
self.prev=n_prev
self.next=n_next
self.key=key
class DoublyLinkedList:
def __init__(self,head):
self.head=head
def list_search(self,k):
x=self.head
while x !=None and x.key!=k:
x=x.next
return x
def list_insert(self,x):
x.next=self.head
if self.head != None:
self.head.prev=x
self.head=x
x.prev=None
def list_delete(self,x):
if x.prev!=None:
x.prev.next=x.next
else:
self.head=x.next
if x.next !=None:
x.next.prev=x.prev
运行结果:
>>> head = DoublyNode(None,None,9)
>>> L=DoublyLinkedList(head)
>>> x=DoublyNode(None,None,16)
>>> L.list_insert(x)
>>> L.head.key
16
>>> L.head.next
<__main__.DoublyNode object at 0x035BDFB0>
>>> L.head.next.key
9
x=DoublyNode(None,None,4)
>>> L.list_insert(x)
x=DoublyNode(None,None,4)
>>> L.list_insert(x)
有哨兵的双向循环链表:
哨兵是一个哑对象,其作用是简化边界条件的处理。
哨兵
##有哨兵的双向循环链表
class DoublyLinkedList2:
def __init__(self,nil):
self.nil=nil
def list_search(self,k):
x=self.nil.next
while x !=self.nil and x.key!=k:
x=x.next
return x
def list_insert(self,x):
x.next=self.nil.next
self.nil.next.prev=x
self.nil.next=x
x.prev=self.nil
def list_delete(self,x):
x.prev.next=x.next
x.next.prev=x.prev
运行:
>>> nil=DoublyNode(None,None,0)
>>> nil.next
>>> nil
<__main__.DoublyNode object at 0x03650D70>
>>> nil.next=nil
>>> nil.next
<__main__.DoublyNode object at 0x03650D70>
>>> nil.prev
>>> nil.prev=nil
>>> L2=DoublyLinkedList2(nil)
>>> x=DoublyNode(None,None,1)
>>> L2.list_insert(x)
>>> x=DoublyNode(None,None,4)
>>> L2.list_insert(x)
>>> x=DoublyNode(None,None,9)
>>> L2.list_insert(x)
>>> x=DoublyNode(None,None,16)
>>> L2.list_insert(x)
>>> y=L2.list_search(1)
>>> y.next
<__main__.DoublyNode object at 0x03650D70>
>>> y.next.key
0
>>> y.next.next.key
16