Re-ordering a Linked List in Python

后端 未结 2 1997
暖寄归人
暖寄归人 2021-01-28 13:54

I realize this sort of data structure is better done with built in list type, but I\'m trying to understand this more for academic reasons. Given that I have a linked list like

2条回答
  •  半阙折子戏
    2021-01-28 14:38

    It saddens me that the "doubly-linked-list-with-null-header" data structure has not caught on more. In this structure, each node points to its previous and next elements, and the list itself starts with a null Node, which is a header only, and never actually has any data. In the initial empty list, the null header node's next and prev pointers point back to the node itself. With this simple initialization, the rest of the linking and unlinking code can be implemented with hardly any "if next is not None" or "if prev is not None" stuff - the next and prev pointers are never None! Look at the simplicity of add_before, add_after, and remove, and then see how easily reorder is done. Like a deque, insertion at the beginning or end of the list is O(1) - just call self.header.add_after to insert at the head, or self.header.add_before to insert at the end.

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

提交回复
热议问题