-3

Trying figure out why Hoare quick sort works correctly. Basically I can't prove to myself that we can not create an array that will cause fail for Hoare sorting algorithm. Prove not necessary to be 100% mathematics. I just want to believe that algorithm works.

In the code below I rewrite some part of the algorithm to make it more clear to me (the basic idea stay the same).

void quickSort(int[] arr, int start, int end) {
  int pivotIndex = partition(arr, start, end);

  if (start < pivotIndex - 1) quickSort(arr, start, pivotIndex - 1);
  if (end >= pivotIndex) quickSort(arr, pivotIndex, end);
}

int partition(int[] arr, int leftIndex, int rightIndex) {
    int pivot = arr[(leftIndex + rightIndex) / 2];

    while (true) {
        while (arr[leftIndex] < pivot) leftIndex++;
        while (arr[rightIndex] > pivot) rightIndex--;

        if (leftIndex == rightIndex) return leftIndex + 1;

        if (leftIndex < rightIndex) {
          swap(arr, leftIndex, rightIndex);
          leftIndex++;
          rightIndex--;
        }
        if (leftIndex > rightIndex) return leftIndex;
    }
}

What I'm 100% sure about that function:

  1. Function shoul partion array into two sub arrays
    • low -- contains elements less or equal to pivot
    • high -- contains elements greater or qual to pivot
  2. When partition done, leftIndex couldn't be greater rightIndex more than 1. In other words: leftIndex - rightIndex equals ONLY to 0 or 1.
  3. Function always returns first index of the first element in high sub array

What I totally don't understand:

First question:

Why if code

if (leftIndex < rightIndex) { 
    swap(arr, leftIndex, rightIndex);
    leftIndex++;
    rightIndex--;
}

has been executed, and after that leftIndex becomes equals rightIndex, it doesn't mean that array has been successfully partitioned and we could return leftIndex + 1? To clarify my idea, look at the code below:

int partition(int[] arr, int leftIndex, int rightIndex) {
    int pivot = arr[(leftIndex + rightIndex) / 2];

    while (true) {
        while (arr[leftIndex] < pivot) leftIndex++;
        while (arr[rightIndex] > pivot) rightIndex--;

        // remove line from here    
        //if (leftIndex == rightIndex) return leftIndex + 1;

        if (leftIndex < rightIndex) {
          swap(arr, leftIndex, rightIndex);
          leftIndex++;
          rightIndex--;
        }
        // move it here. If I do that, code stop working and sort array in a wrong way
        //sorce array: [6, 3, 12, 10, 3, 8, 5, 8, 11, 2, 9]
        //final array: [2, 3, 3, 5, 6, 8, 8, 9, 10, 12, 11] - 12 and 11 at wrong places
        if (leftIndex == rightIndex) return leftIndex + 1;

        if (leftIndex > rightIndex) return leftIndex;
    }
}

Second question:

Let's imaging the following scenario. Let say pivot value was 10 and code below has been successfully executed:

    01 while (arr[leftIndex] < pivot) leftIndex++;
    02 while (arr[rightIndex] > pivot) rightIndex--;
    03 if (leftIndex == rightIndex) return leftIndex + 1;

After that, let say that leftIndex and rightIndex stoped at element with index X and value = 6 i.e. arr[X] -> 6. Line 3 will return index X + 1 with value, let say 8. So basically we will have sub arrays:

[..., ...] and [8, ..., 10, ...]

So high sub array will contain element less than pivot. Is it possible to create such array to replicate that scenario?

No Name QA
  • 724
  • 1
  • 6
  • 20
  • "has been executed, and after that leftIndex becomes equals rightIndex, it doesn't mean that array has been successfully partitioned and we could return leftIndex + 1?" - that **is** what happens. – Oliver Charlesworth Dec 22 '17 at 14:12
  • @OliverCharlesworth I added sorting call of partition function. About your comment: I don't understand **why** it happens – No Name QA Dec 22 '17 at 14:14
  • Presumably you can debug that specific case to see what's going on? – Oliver Charlesworth Dec 22 '17 at 14:58
  • @OliverCharlesworth I have already spent 2 months (about 8-10 hours per day) to understand why Hoare algorithm works. I debugged it for thousand of arrays. But I still can not believe that it works correctly, because I don't see all the cases. I'm exhausted. I need a prove. – No Name QA Dec 22 '17 at 15:10

1 Answers1

0

This might answer your overall question about how to prove the Hoare algorithm. This online PDF gives both a formal and an informal proof. Here is the informal one (it's an image because the pdf doesn't have text, it's just an image itself):

first half of informal proof second half of informal proof

Keara
  • 589
  • 1
  • 6
  • 17
  • Hello! I've seen you do a lot of good edits lately; keep up the good work! However, [this edit](https://stackoverflow.com/review/suggested-edits/20252150) included an edit explanation (from _your_ point of view) in the actual post. That shouldn't be there. Either put that in the edit summary or in a comment. I used to comment when I suggested similar edits to oddly written posts, hoping the author would notice and say "Yes, that's what I meant". (Of course, some of these questions... might not be worth editing.) I approved your edit because it was good otherwise. Cheers! – Andrew Myers Jul 10 '18 at 03:45
  • @AndrewMyers Hi - thanks! Yes, I tried not to include that in the edit (I agree that it isn't good in general to leave notes from the editor's perspective.) In that case, the original poster only posted their code, and the edit page wouldn't let me submit an edit that was "mostly code". So, I just tried to think of the least intrusive way to add plain text so I could submit the edit and make the question readable. (It would have been good if OP had posted more detail in plain text originally.... but oh well!) Thanks again for the good advice. – Keara Jul 10 '18 at 04:35