在Python中重新排序链接列表

时间:2011-07-29 20:17:46

标签: python data-structures linked-list

我意识到使用内置列表类型可以更好地完成这种数据结构,但我试图通过学术原因更多地理解这一点。鉴于我有一个这样的链表:

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()

有什么想法吗?

2 个答案:

答案 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()