0

I am trying to implement the quick sort based on a pseudocode I was given, and I understand how the algorithm works.
When I run a test on the function and the input list is randomized, it runs perfectly fine.
Yet, when I run a descending or ascending sorted list through the function I get the error of maximum recursion depth. To my understanding, it is because the pivot I chose was not randomized, as in inputs of elements 900 and under, the code works fine, but once I put 1000 elements for a list that is not randomized I receive that error. I am unsure how to go about randomizing it without using the rand function.
I also tried using the mid point, but my output is incorrect and I cannot figure out why.
Any help and explanation would be appreciated.

    def quicksort(self, query_list, left, right):
        if left < right:
            mid = self.partition(query_list, left, right)
            self.quicksort(query_list, left, mid - 1)
            self.quicksort(query_list, mid + 1, right)

    def partition(self, query_list, beg, end):
        pivot = query_list[end]
        i = beg - 1
        for j in range(beg, end):
            if query_list[j] >= pivot:
                i = i + 1
                (query_list[i], query_list[j]) = (query_list[j], query_list[i])
        (query_list[i + 1], query_list[end]) = (query_list[end], query_list[i + 1])
        return i + 1

Input a list rand: [3, 4, 8, 2, 0, 1]
Output: [8, 4, 3, 2, 1, 0]

I tried:

mid = (beg + end) // 2
pivot = query_list[mid]

My results:
Input list at random: [8, 2, 4, 1, 9, 3, 7, 10, 6, 5]
Output: [10, 9, 8, 6, 7, 1, 4, 3, 5, 2]

4
  • wiki page describes "median of three" method to choose pivot and gives some words about optimization due to partial or full recursion elimination. I'd recommend to look in Sedgewick Algorithms book. Commented Oct 3, 2022 at 8:41
  • Check what return values you are getting from your partition function. Commented Oct 3, 2022 at 8:45
  • When selecting query_list[end] for pivot, the pivot gets swapped with the value at the index returned. What is the value there when you choose query_list[mid]? Commented Oct 3, 2022 at 10:03
  • With a sorted list, your pivot pick query_list[end] will always give you one empty partition and one partition containing the rest of the array. That is maximally inefficient, hence the maximum recursion depth. As @MBo suggested, using 'median of three' will give better results. Commented Oct 3, 2022 at 14:31

1 Answer 1

1

To use middle element as pivot with the Lomuto partition scheme used in the question, swap middle element with last element:

    def partition(self, query_list, beg, end):
        mid = (beg+end)/2
        query_list[mid],query_list[end] = query_list[end],query_list[mid]
        pivot = query_list[end]
Sign up to request clarification or add additional context in comments.

2 Comments

"with the Lomuto partition scheme used in the question" What are you referring to? I don't see anything like that in the OP.
@KarlKnechtel - Hoare used 2 indexes, one scans left to right, the other right to left. Lomuto uses a single index that scans left to right.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.