'Quick Sort on a Doubly Linked List (Python)
I have been trying to figure out and understand how to quick sort on a doubly linked list in python. I have a good understanding of how the quick sort is supposed to work however I have not been able to solve this problem. I have tried reading and implementing many versions online but it seems that even some of the code snippets online are not 100% correct. For example, I pulled code from an online source that, yes indeed performed a quick sort on the numbers they inputted. However this was not the case with a totally random set of numbers. I want a program that will run for any set of numbers, not just some. With all that being said here is my code that sometimes works but not for all sets of numbers. Any help would be greatly appreciated!
# A python program to sort a linked list using Quicksort
# A class that will function as a linked list
class LL_numbers:
def __init__(self):
self.head = None
self.tail = None
# Function that will insert a new node to the end of the linked list
def push(self, new_data):
new_node = Node(new_data)
# If the head is empty fill the head and tail with the new node
if(self.head == None):
self.head = new_node
self.tail = new_node
return
# If the head is not empty, find the last element (tail) and add an element to the tail
self.tail.next = new_node
new_node.prev = self.tail
self.tail = new_node
def print_list(self):
current = self.head
while(current):
print(current.data, end=", ")
current = current.next
def partition(self,left,right):
i = left.prev
pivot = right
j = left
while(j != right):
if j.data <= pivot.data:
# Increment i
if i == None:
i = left
else:
i = i.next
i.data, j.data = j.data, i.data
j = j.next
# increment i
if i == None:
i = left
else:
i = i.next
i.data, right.data = right.data, i.data
return i
def quickSort(self,left,right):
if(right != None and left != right and left != right.next):
p = self.partition(left,right)
self.quickSort(left, p.prev)
self.quickSort(p.next,right)
# A node of the doubly linked list
class Node:
def __init__(self,d):
self.data = d
self.next = None
self.prev = None
def main():
linked_numbers = LL_numbers()
# 5, 3, 2, 4, 3, 9, 0, 6, 1, 10,
# for n in range(10):
# rand_val = random.randint(0,10)
# linked_numbers.push(rand_val)
linked_numbers.push(5)
linked_numbers.push(3)
linked_numbers.push(2)
linked_numbers.push(4)
linked_numbers.push(3)
linked_numbers.push(9)
linked_numbers.push(0)
linked_numbers.push(6)
linked_numbers.push(1)
linked_numbers.push(10)
print("Before Quick Sorting:\n")
linked_numbers.print_list()
print("\nAfter Quick Sorting:\n")
print(linked_numbers.tail.data)
linked_numbers.quickSort(linked_numbers.head, linked_numbers.tail)
linked_numbers.print_list()
if __name__ == "__main__":
main()
Output:
Before Quick Sorting:
5, 3, 2, 4, 3, 9, 0, 6, 1, 10,
After Quick Sorting:
10
5, 1, 0, 2, 3, 3, 4, 6, 9, 10,
Solution 1:[1]
The problem is in partition in the body of the loop:
if i == None:
i = left
else:
i = i.next
i.data, j.data = j.data, i.data
The swap should also happen in the if case, so it should be moved out of the else block:
if i == None:
i = left
else:
i = i.next
i.data, j.data = j.data, i.data
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | trincot |
