Skip to content

Commit

Permalink
writing expalanatory notes on quick sort Hoare implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
rohan-paul committed Jul 23, 2018
1 parent 25d21eb commit 912813b
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 23 deletions.
2 changes: 2 additions & 0 deletions Sort/QuickSort/README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Quick Sort

The quicksort algorithm basically works by partitioning the entire array, and then recursively partitioning the left and right parts of the array until the entire array is sorted. The left and right parts of the array are determined by the index returns after each partition operation. That index effectively becomes the boundary between the left and right parts of the array.

The algorithm for Quicksort is:

1. Pick a pivot element that divides the list into two sublists.
Expand Down
42 changes: 32 additions & 10 deletions Sort/QuickSort/quick-sort-Hoare.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,22 @@
// First write the swap function, which is just a helper function to swap values of the array.
function swap(array, i, j) {
var temp = array[i];
array[i] = array[j];
array[j] = temp;
}

// function swap(array, i, j) {
// var temp = array[i];
// array[i] = array[j];
// array[j] = temp;
// }

const swap = (arr, i, j) => [ arr[i], arr[j] ] = [ arr[j], arr[i] ]

/* In the below quickSortHoare() function, I am invoking the function recursively with the below condition. So once this condtion is no more applicable, that will mean the terminal condition has been reached to stop the recursion.
If left is less than the returned index minus 1 then there are still items on the left to be sorted and quickSort() is called recursively on those items. Likewise, if index is less than the right pointer then there are still items on the right to sort. Once all this is done, the array is returned as the result. */

function quicksortHoare(array, left, right) {

// To optimize for performance, the array isn’t sorted if it has zero or one items. If there are two or more items in the array then it is partitioned.
if (arr.length < 2) return arr;

// left-pointer would be the index of the first element which is 0 and right-pointer would be the index of the last element which would be (length -1).
left = left || 0;
right = right || array.length - 1;
Expand All @@ -24,12 +35,20 @@

}

/* Two indices that start at the ends of the array being partitioned, then move toward each other, until they detect an inversion: a pair of elements, one greater than the pivot, one smaller, that are in the wrong order relative to each other. The inverted elements are then swapped.
Here the numerical values of left and right is continually getting updated with each inner while loop. But only if the while loop condition gets satisfied. That is, when the while loop condition is unsatisfied, e.g. for the first inner while loop, when array[left] > array[pivot] which means we have found a misplaced pair.
/* A> Two indices that start at the ends of the array being partitioned, then move toward each other, until they detect an inversion: a pair of elements, one greater than the pivot, one smaller, that are in the wrong order relative to each other. The inverted elements are then swapped.
B> Here the numerical values of left and right is continually getting updated with each inner while loop. But only if the while loop condition gets satisfied. That is, when the while loop condition is unsatisfied, e.g. for the first inner while loop, when array[left] > array[pivot] which means we have found a misplaced pair.
C> That is, although the left <= right (which is being made sure by the outer while loop's condition) the actual pair of the array-elements are not sorted. Meaning a left side element is larger in value than the right side element. So, the code execution then jumps out of the inner while loop and goes right in to execute the swap function.
D> The entire algorithm is just a loop of loops. The outer loop determines when all of the items in the array range have been processed. The two inner loops control movement of the left and right pointers. When both of the inner loops complete, then the pointers are compared to determine if the swap is necessary. After the swap, both pointers are shifted so that the outer loop continues in the right spot.
This partitionHoare function returns the value of the left pointer because this is used to determine where to start partitioning the next time. Keep in mind that the partitioning is happening in place, without creating any additional arrays.
*/

That is, although the left <= right (which is being made sure by the outer while loop) the actual elements are not sorted. Meaning a left side element is larger in value than the right side element. So, the code execution then jumps out of the inner while loop and goes right in to execute the swap function.
*/
function partitionHoare(array, left, right) {

var pivot = Math.floor((left + right) / 2);

while (left < right) {
Expand All @@ -49,10 +68,13 @@
return left;
}


/* The pivot value is determined by adding together the left and right values and then dividing by 2. Since this value could potentially be a floating-point number, it’s necessary to perform some rounding. In this case, I chose to use the floor function, but I could have just as well use the ceiling function or round function with some slightly different logic. */

/******************* Testing Hoare algorithm *********************/

// First 2 test cases to check the output value of partitionHoare()
console.log(partitionHoare([ 2, 8, 6, 0, 1], 0, 4)) // => 3
console.log(partitionHoare([ 0, 1, 2, 3, 4], 0, 4)) // => 3

let arr = Array.from({length : 20}, () => Math.floor(Math.random() * 20));
console.log(arr); //printing unsorted array
Expand Down
16 changes: 3 additions & 13 deletions Sort/QuickSort/quick-sort-basic-Recursive-FUTURE-REFERENCE.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,10 @@
/*The algorithm for Quicksort is:
1. Pick a pivot element that divides the list into two sublists.
2. Reorder the list so that all elements less than the pivot element are placed before
the pivot and all elements greater than the pivot are placed after it.
3. After this partitioning, the pivot is in its final position. This is called the partition operation.
3. Repeat steps 1 and 2 on both the list with smaller elements and the list of larger
elements.
4. Quicksort is a divide and conquer algorithm in the style of merge sort. The basic idea is to find a “pivot” item in the array to compare all other items against, then shift items such that all of the items before the pivot are less than the pivot value and all the items after the pivot are greater than the pivot value. After that, recursively perform the same operation on the items before and after the pivot. */
/* */

// basic recursive implementation, where pivot is the first element, without using swap function and partition function.

function quickSortBasic(array) {

// To optimize for performance, the array isn’t sorted if it has zero or one items. If there are two or more items in the array then it is partitioned.
if(array.length < 2) {
return array;
}
Expand Down

0 comments on commit 912813b

Please sign in to comment.