Quick sort explanation on an assignment - java

I am writing a specific variant of quicksort class. However; the directions on this variant of quick sort is confusing me. I have written the code for quick sort, but I do not understand the description. Can anyone help me understand this description means for the variant so I can finalize it?
Description: implement a variant of quicksort with pivots chosen according to pivot_pos. That is, whenever the quicksort makes a recursive call to quicksort a subarray (A, p, r), it chooses as the pivot min(p+pivot,r).
To my interpretation, this is saying to include within the if statement of quicksort a int value of min(p + pivot, r). It would partition the array with the pivot representing this value, and quicksorting the array with this value as well.
public static int partition(int[] a, int p, int r)
{
int x = a[r];
int i = p - 1;
for( int j = p; j <= r - 1; j++)
{
if(a[j] <= x)
{
i++;
swap(a, i, j);
}
}
swap(a, i + 1, r);
return i + 1;
}
public static void quick_sort(int[] a, int p, int r)
{
if(p < r)
{
int q = partition(a, p, r);
quick_sort(a, p, q - 1);
quick_sort(a, q + 1, r);
}
}

Related

Randomized-select kth largest element

I have been studying algorithms recently, and got to the randomized select algorithm. Im trying to figure it out, and stumbled upon this website
https://www.geeksforgeeks.org/kth-smallestlargest-element-unsorted-array-set-2-expected-linear-time/
Which shows a code, with little to no explanation of how it works.
It works to find the kth smallest element, but how could it be changed in order to show the kth largest element?
Particularly on this method
int kthSmallest(int arr[], int l, int r, int k)
{
// If k is smaller than number of elements in array
if (k > 0 && k <= r - l + 1)
{
// Partition the array around a random element and
// get position of pivot element in sorted array
int pos = randomPartition(arr, l, r);
// If position is same as k
if (pos-l == k-1)
return arr[pos];
// If position is more, recur for left subarray
if (pos-l > k-1)
return kthSmallest(arr, l, pos-1, k);
// Else recur for right subarray
return kthSmallest(arr, pos+1, r, k-pos+l-1);
}
// If k is more than number of elements in array
return Integer.MAX_VALUE;
}
You don't have to modify this method kthSmallest. Instead you should modify method partition (taken from the link you provided):
int partition(int arr[], int l, int r)
{
int x = arr[r], i = l;
for (int j = l; j <= r - 1; j++)
{
if (arr[j] >= x)
{
swap(arr, i, j);
i++;
}
}
swap(arr, i, r);
return i;
}
I changed here the if statement : if (arr[j] <= x) to if (arr[j] >= x)

Quicksort Counter Example

Firstly (as the question title implies) I'm not looking for why the bellow partitioning method doesn't work, rather a modification to it so that it will work for the following input:
int[] a = {1,2,8,4,5,7};
Here's the partition method along with some other stuff:
static int[] swap (int[] a,int i,int j){
int t = a[i];
a[i] = a[j];
a[j] = t;
return a;
}
static int partition (int[] a,int l,int r){
int i = l;
int j = r;
int v = a[l];
while (true) {
while (a[i] < v) {
if (i == r) break;
i++;
}
while (a[j] > v) {
if (j == l) break;
j--;
}
if (i >= j) break;
a = swap(a,i,j);
}
a = swap(a, l, j);
return j;
}
void sort(int[] a,int l,int r){
int j = partition(a, l, r);
sort(a, l, j-1);
sort(a, j+1, r);
}
public static void main(String[] args) {
int[] a = {1,2,8,4,5,7};
System.out.println(partition(a,0,5));
}
Output:
0
The output is the index of the pivot returned from the partition method. 0, as the index of the pivot, makes sense in terms of the definition, i.e. everything left of the pivot is smaller and everything right of the pivot is larger, but clearly runs into a problem in sort namely:
sort(a, l, j-1);
where you have the right pointer being negative (j-1 = 0-1 = -1). My question again being is there a modification to the above method(s) that will maintain the definition (everything left of the pivot is smaller and everything right of the pivot is larger) and not run into the problem in sort.
The missing part is the line
if ( l >= r ) return;
in the beginning of the sort method. This is actually the recursion stop step so it is necessary to have it anyway to prevent endless recursion. But besides that, it also solves your problem, because if you call sort(0,-1) then -1 is less than 0, so it prevents further processing of that index.

Working with quicksort

I am working on a quicksort from my data structures and algorithms book. In the book it lists a quicksort method then a hoare partition that it wants you to use with the quick sort. I seem to be having an issue where my hoare partition is using out of bounds numbers on the array. Either it uses 8 or if I try to fix that it goes to -1. Am I converting the books pseudo correctly into java?
Quicksort pseudo code
QuickSort(A, p, r)
if p<r
q = partition(A, p, r);
QuickSort(A, p, q - 1);
QuickSort(A, q, r);
Hoare-Partition Pseudo Code
Hoare-Partition(A,p,r)
x= A[p]
i = p-1
j=r+1
while true
repeat
j=j-1
until A [j] <= x
repeat
i = i +1
until A[i] >= x
if i < l
exchange A[i] with A[j]
else return j
My code
public class RunSort {
/**
* #param args
*/
public static void main(String[] args) {
int[] sortNumbers = {4,5,6,2,3,7,2,1};
int[] sorted = new int[sortNumbers.length];
sorted = QuickSort(sortNumbers, 1, sortNumbers.length);
System.out.print(sorted);
}
public static int[] QuickSort(int[] A, int p, int r){
if(p < r){
int q = partition(A, p, r);
QuickSort(A, p, q - 1);
QuickSort(A, q, r);
}
return A;
}
public static int partition(int[] A, int p, int r){
int x = A[p];
int i = p - 1;
int j = r + 1;
int temp;
while(true){
while(A[j] <= x && j != 0){
j--;
}
while(A[i] >= x && i != A.length){
i++;
}
if(i < j){
temp = A[i];
A[i] = A[j];
A[j] = temp;
}else{
return j;
}
}
}
}
Hint: repeat {...} until (condition) does not do the same thing as while (condition) {...}.
Depending on the text, pseudocode often uses 1..arrayLength as the index bounds on an array, but in Java, et al., it's 0..arrayLength-1. You'll need to adjust the arguments to the main QuickSort call in main.
(As a nitpick, QuickSort should start with a lowercase letter by convention.)

selection sort method Java

I am not sure what this line exactly means.
Could anyone kindly explain what "comma" in (a, n) does exactly, please ? Also what is the difference between (a, n) and (a, minPos, n)?
* Sorts an array by the "selection sort" method.
* Find the position of the smallest element in the array,
* swap it with the next unsorted element
*
* #param a the array to sort
*/
public static void sort(int[] a)
{
for (int n = 0; n < a.length - 1; n++)
{
int minPos = minimumPosition(a, n);
if (minPos != n)
{
swap(a, minPos, n);
}
}
public static int minimumPosition(int[] a, int from)
{
int minPos = from;
for (int i = from + 1; i < a.length; i++)
{
if (a[i] < a[minPos])
{
minPos = i;
}
}
return minPos;
}
}
By using (a,n) in
minimumPosition(a, n);
You are passing value of a and n to method
public static int minimumPosition(int[] a, int from)
.a will be passed to the first argument of method minimumPosition and value of n will be passed to second argument
(a,n) means a and n are arguments to the method call minimumPosition(int[] a, int from) similar is the meaning of (a, minPos, n) I explained from a basic view point hope this is what you wanted to know

3-way quicksort, question

I am trying to understand the 3-way radix Quicksort, and i dont understand why the the CUTOFF variable there? and the insertion method?
public class Quick3string {
private static final int CUTOFF = 15; // cutoff to insertion sort
// sort the array a[] of strings
public static void sort(String[] a) {
// StdRandom.shuffle(a);
sort(a, 0, a.length-1, 0);
assert isSorted(a);
}
// return the dth character of s, -1 if d = length of s
private static int charAt(String s, int d) {
assert d >= 0 && d <= s.length();
if (d == s.length()) return -1;
return s.charAt(d);
}
// 3-way string quicksort a[lo..hi] starting at dth character
private static void sort(String[] a, int lo, int hi, int d) {
// cutoff to insertion sort for small subarrays
if (hi <= lo + CUTOFF) {
insertion(a, lo, hi, d);
return;
}
int lt = lo, gt = hi;
int v = charAt(a[lo], d);
int i = lo + 1;
while (i <= gt) {
int t = charAt(a[i], d);
if (t < v) exch(a, lt++, i++);
else if (t > v) exch(a, i, gt--);
else i++;
}
// a[lo..lt-1] < v = a[lt..gt] < a[gt+1..hi].
sort(a, lo, lt-1, d);
if (v >= 0) sort(a, lt, gt, d+1);
sort(a, gt+1, hi, d);
}
// sort from a[lo] to a[hi], starting at the dth character
private static void insertion(String[] a, int lo, int hi, int d) {
for (int i = lo; i <= hi; i++)
for (int j = i; j > lo && less(a[j], a[j-1], d); j--)
exch(a, j, j-1);
}
// exchange a[i] and a[j]
private static void exch(String[] a, int i, int j) {
String temp = a[i];
a[i] = a[j];
a[j] = temp;
}
// is v less than w, starting at character d
private static boolean less(String v, String w, int d) {
assert v.substring(0, d).equals(w.substring(0, d));
return v.substring(d).compareTo(w.substring(d)) < 0;
}
// is the array sorted
private static boolean isSorted(String[] a) {
for (int i = 1; i < a.length; i++)
if (a[i].compareTo(a[i-1]) < 0) return false;
return true;
}
public static void main(String[] args) {
// read in the strings from standard input
String[] a = StdIn.readAll().split("\\s+");
int N = a.length;
// sort the strings
sort(a);
// print the results
for (int i = 0; i < N; i++)
StdOut.println(a[i]);
}
}
from http://www.cs.princeton.edu/algs4/51radix/Quick3string.java.html
It would appear to be used in order to invoke insertion sort for sufficiently small (size <= 15) arrays. This is most likely to speed up sorting.
It's a simple optimization of quicksort algorithm. The cost of recursive calls in quicksort are quite high, so for small arrays insertion sort works better. So, the idea is, that if length of subarray to be sorted os below certain threshold, it's better to sort it using insertion sort than quicksort. In your example, CUTOFF variable defines that threshold, i.e. if less than 15 elements are left, they are sorted using insertion sort instead of quicksort.
The sort method above is a recursive method. And every recursive method should have some kind of base case (otherwise it will keep calling itself, eventually leading to a stack overflow).
The insertion part is the base case in that method, because at every recursive step, the hi-lo difference keeps decreasing, & when its less than CUTOFF, the insertion sort will eventually be triggered, forcing the recursion to stop.
if (hi <= lo + CUTOFF) { // base case
insertion(a, lo, hi, d);
return;
}
Now, why insertion ? Because it works well for small arrays.
More on sorting here: http://www.sorting-algorithms.com/
This idea comes from Robert Sedgewick, who knows more about Quicksort than probably any man alive. It is cited in Donald E. Knuth, The Art of Computer Programming, Volume III, where he shows that for small M, insertion sort is faster than Quicksort, so he recommends not sorting small partitions < M at all and leaving it to one final insertion sort over the whole data set at the end. Knuth gives a function for calculating M (which is your CUTOFF), and which is 9 for his MIX pseudo-computer.

Categories

Resources