📜  用于单链表上快速排序的Python程序

📅  最后修改于: 2022-05-13 01:55:00.863000             🧑  作者: Mango

用于单链表上快速排序的Python程序

此处讨论双向链表上的快速排序。单链表上的快速排序作为练习给出。关于实现的重要事情是,它改变指针而不是交换数据,时间复杂度与双链表的实现相同。

排序图像

partition()中,我们将最后一个元素视为枢轴。我们遍历当前列表,如果一个节点的值大于枢轴,我们将其移动到尾部。如果节点的值较小,我们将其保持在当前位置。

QuickSortRecur()中,我们首先调用 partition() ,它将枢轴放置在正确的位置并返回枢轴。枢轴放置在正确位置后,我们找到左侧的尾节点(枢轴之前的列表)并为左列表递归。最后,我们递归右列表。

Python3
# Sort a linked list using quick sort
class Node:
    def __init__(self, val):
        self.data = val
        self.next = None
  
class QuickSortLinkedList:
    def __init__(self):
        self.head=None
  
    def addNode(self, data):
        if (self.head == None):
            self.head = Node(data)
            return
  
        curr = self.head
        while (curr.next != None):
            curr = curr.next
  
        newNode = Node(data)
        curr.next = newNode
  
    def printList(self, n):
        while (n != None):
            print(n.data, end = " ")
            n = n.next
  
    ''' Takes first and last node,but do not
        break any links in the whole linked list'''
    def paritionLast(self, start, end):
        if (start == end or 
            start == None or end == None):
            return start
  
        pivot_prev = start
        curr = start
        pivot = end.data
  
        ''' Iterate till one before the end, 
            no need to iterate till the end 
            because the end is pivot '''
        while (start != end):
            if (start.data < pivot):
                
                # Keep tracks of last 
                # modified item
                pivot_prev = curr
                temp = curr.data
                curr.data = start.data
                start.data = temp
                curr = curr.next
            start = start.next
  
        ''' Swap the position of curr i.e. 
            next suitable index and pivot'''
        temp = curr.data
        curr.data = pivot
        end.data = temp
  
        ''' Return one previous to current 
            because current is now pointing 
            to pivot '''
        return pivot_prev
  
    def sort(self, start, end):
        if(start == None or 
           start == end or start == end.next):
            return
  
        # Split list and partion recurse
        pivot_prev = self.paritionLast(start, 
                                       end)
        self.sort(start, pivot_prev)
  
        ''' If pivot is picked and moved to 
            the start, that means start and 
            pivot is the same so pick from 
            next of pivot '''
        if(pivot_prev != None and 
           pivot_prev == start):
            self.sort(pivot_prev.next, end)
  
        # If pivot is in between of the list, 
        # start from next of pivot, since we 
        # have pivot_prev, so we move two nodes
        elif (pivot_prev != None and 
              pivot_prev.next != None):
            self.sort(pivot_prev.next.next, 
                      end)
  
# Driver code
if __name__ == "__main__":
    ll = QuickSortLinkedList()
    ll.addNode(30)
    ll.addNode(3)
    ll.addNode(4)
    ll.addNode(20)
    ll.addNode(5)
  
    n = ll.head
    while (n.next != None):
        n = n.next
  
    print("Linked List before sorting")
    ll.printList(ll.head)
  
    ll.sort(ll.head, n)
  
    print("Linked List after sorting");
    ll.printList(ll.head)
# This code is contributed by humpheykibet


输出:

Linked List before sorting 
30 3 4 20 5 
Linked List after sorting 
3 4 5 20 30 

有关详细信息,请参阅有关单链表快速排序的完整文章!