让我难过的是,“带空头的双链表”数据结构还没有流行起来。在这个结构中,每个节点都指向它的前一个和下一个元素,和列表本身以一个空节点开始,它只是一个头,实际上从来没有任何数据。在初始空列表中,空头节点的next和prev指针指向节点本身。通过这个简单的初始化,其余的链接和取消链接代码几乎可以用任何“if next is not None”或“if prev not None”来实现——next和prev指针都是neverNone!看看前面添加、后面添加和删除的简单性,然后看看重新排序是多么容易。像deque一样,在列表的开始或结尾处的插入是O(1)-只需调用self.header.add_after在头部插入,或者调用{}在末尾插入。在class Node:
def __init__(self):
self.cargo = None
self.next = self
self.prev = self
def add_after(self, other):
other.next = self.next
other.prev = self
self.next.prev = other
self.next = other
def add_before(self, other):
other.next = self
other.prev = self.prev
other.prev.next = other
self.prev = other
class LinkedList:
def __init__(self):
self.header = Node()
def __bool__(self):
return self.header.next != self.header
__nonzero__ = __bool__ # for older Pythons
def empty(self):
return not self
def add_node(self, cargo):
new_node = Node()
new_node.cargo = cargo
self.header.add_before(new_node)
@staticmethod
def pop(node):
node.prev.next = node.next
node.next.prev = node.prev
node.next = node.prev = node
return node
def print_list(self):
node = self.header.next
while node != self.header:
print node.cargo
node = node.next
def reorder(self):
node = self.header.next
while node != self.header and node.next != self.header:
node.add_before(self.pop(node.next))
node = node.next
ll = LinkedList()
ll.add_node("a")
ll.add_node("b")
ll.add_node("c")
ll.add_node("d")
ll.add_node("e")
ll.add_node("f")
ll.print_list()
ll.reorder()
ll.print_list()