我意识到使用内置列表类型可以更好地完成这种数据结构,但我试图通过学术原因更多地理解这一点。鉴于我有一个这样的链表:
a - > b - > c - > d - > e - > ˚F
我想更改对
的引用b - > a - > d - > c - > f - > ë
换句话说,每对都会被切换。我正在使用这两个类来创建链表。
class Node:
def __init__(self):
self.cargo = None
self.next = None
class LinkedList:
def __init__(self):
self.cur_node = None
def add_node(self, cargo):
new_node = Node()
new_node.cargo = cargo
new_node.next = self.cur_node
self.cur_node = new_node
def print_list(self):
node = self.cur_node
while node:
print node.cargo
node = node.next
def reorder(self):
# missing code here!
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.reorder()
ll.print_list()
有什么想法吗?
答案 0 :(得分:3)
有时候,最好的办法是首先考虑“最佳解决方案的速度有多快?”这似乎很明显是O( length ),所以在列表中运行的东西,最好是一次,就会像你一样好。
鉴于此,你可能会发现最简单的选择是最好的。在伪代码中,它将是
get the first element in left
get the second element in right
append them to a new list as right->left
repeat until you run out of list.
正如Matt和Jodaka所说,如果允许奇数长度列表,你需要决定如何处理奇数列表。
答案 1 :(得分:2)
令我感到遗憾的是,“带有双重链接列表的空标题”数据结构还没有引起更多的关注。在此结构中,每个节点指向其上一个和下一个元素和,列表本身以空节点开始,该节点仅为标头,并且实际上从不具有任何数据。在初始空列表中,空标头节点的next和prev指针指向节点本身。通过这个简单的初始化,其余的链接和取消链接代码几乎都可以实现“if next is not None”或“if prev is not None”的东西 - 下一个和prev指针是从不没有!查看add_before,add_after和remove的简单性,然后看看如何轻松地重新排序。像双端队列一样,列表开头或结尾的插入是O(1) - 只需要调用self.header.add_after
插入头部,或self.header.add_before
插入到末尾。
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()