双链表也可以定义为循环链表,让表尾结点的 next 指向表的首节点,让表首节点的 prev 指向表的尾结点。
节点类:
class Node(object):
def __init__(self, elem, next_=None, prev=None):
self.elem = elem
self.next = next_
self.prev = prev
循环链表类:
class CycleLinkedList(object):
def __init__(self):
self.head = None
def is_empty(self):
return self.head is None
def length(self):
if self.is_empty():
return 0
count = 1
p = self.head.next
while p and p is not self.head:
count += 1
p = p.next
return count
def add(self, elem):
"""首部插入"""
node = Node(elem)
if self.is_empty():
self.head = node
node.prev = node
node.next = node
else:
node.next = self.head
node.prev = self.head.prev
self.head.prev.next = node
self.head.prev = node
self.head = node
def append(self, elem):
"""尾部插入"""
node = Node(elem)
if self.is_empty():
self.head = node
self.head.prev = node
self.head.next = node
else:
node.prev = self.head.prev
node.next = self.head
self.head.prev.next = node
self.head.prev = node
def insert(self, pos, elem):
"""插入"""
if pos <= 0:
self.add(elem)
elif pos > self.length():
self.append(elem)
else:
idx = 0
p = self.head
while idx < pos-1:
idx += 1
p = p.next
node = Node(elem)
node.prev = p
node.next = p
p.next.prev = node
p.next = node
def pop(self):
"""弹出尾部节点"""
if self.is_empty():
return -1
rear = self.head.next
if rear is self.head:
self.head = None
return rear
else:
rear.prev.next = self.head
self.head.prev = rear.prev
rear.prev = None
rear.next = None
return rear
def pop_first(self):
"""弹出首节点"""
if self.is_empty():
return -1
if self.length() == 1:
h = self.head
self.head = None
return h
head = self.head
self.head.next.prev = self.head.prev
self.head.prev.next = self.head.next
self.head = self.head.next
self.head.next = None
self.head.prev = None
return head
def search(self, elem):
if self.is_empty():
return -1
p = self.head
p.prev.next = None
while p:
if p.elem == elem:
return elem
p = p.next
self.head.prev.next = self.head
def reverse(self):
if self.length() == 1:
return
h = self.head
p = self.head.next
while p is not h:
self.head = p
n = p.next
p.next = p.prev
p.prev = n
p = n
def sort(self):
if self.is_empty():
return
p = self.head.next
self.head.next = None
self.head.prev.next = None
self.head.prev = None
rear = p
while p:
rear = p
n = p.next
h = self.head
q = None
while h and h.elem <= p.elem:
q = h
h = h.next
if not q:
self.head = p
else:
q.next = p
if h:
h.prev = p
p.next = h
p.prev = q
p = n
self.head.prev = rear
self.head.prev.next = self.head