|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
The simplified partition( ) algorithm:
// partition(A, s, e): partition A[s]..A[e-1] using pivot A[s]
public static <T extends Comparable<T>> int partition(T[] A, int s, int e)
{
T pivot = A[s];
int low = s+1, high = e-1;
while (low <= high)
{
if ( A[high].compareTo(pivot) >= 0 )
{
high--;
}
else
{
exch(A, low, high);
low++;
}
}
exch(A, s, high);
return high;
}
|
Select pivot = A[s]:
// partition(A, s, e): partition A[s]..A[e-1] using pivot A[s]
public static <T extends Comparable<T>> int partition(T[] A, int s, int e)
{
T pivot = A[s];
int low = s+1, high = e-1;
while (low <= high)
{
if ( A[high].compareTo(pivot) >= 0 )
{
high--;
}
else
{
exch(A, low, high);
low++;
}
}
exch(A, s, high);
return high;
}
|
Initialize the low and high indixes:
// partition(A, s, e): partition A[s]..A[e-1] using pivot A[s]
public static <T extends Comparable<T>> int partition(T[] A, int s, int e)
{
T pivot = A[s];
int low = s+1, high = e-1;
while (low <= high)
{
if ( A[high].compareTo(pivot) >= 0 )
{
high--;
}
else
{
exch(A, low, high);
low++;
}
}
exch(A, s, high);
return high;
}
|
As long as low ≤ high (i.e., have not crossed), we compare A[high] against the pivot:
// partition(A, s, e): partition A[s]..A[e-1] using pivot A[s]
public static <T extends Comparable<T>> int partition(T[] A, int s, int e)
{
T pivot = A[s];
int low = s+1, high = e-1;
while (low <= high)
{
if ( A[high].compareTo(pivot) >= 0 )
{
high--;
}
else
{
exch(A, low, high);
low++;
}
}
exch(A, s, high);
return high;
}
|
If A[high] >= pivot, then A[high] belongs to the high portion and we decrement high :
// partition(A, s, e): partition A[s]..A[e-1] using pivot A[s]
public static <T extends Comparable<T>> int partition(T[] A, int s, int e)
{
T pivot = A[s];
int low = s+1, high = e-1;
while (low <= high)
{
if ( A[high].compareTo(pivot) >= 0 )
{
high--;
}
else
{
exch(A, low, high);
low++;
}
}
exch(A, s, high);
return high;
}
|
Otherwise A[high] belongs to the low portion and we (1) swap(A[low],A[high]) and (2) increment low :
// partition(A, s, e): partition A[s]..A[e-1] using pivot A[s]
public static <T extends Comparable<T>> int partition(T[] A, int s, int e)
{
T pivot = A[s];
int low = s+1, high = e-1;
while (low <= high)
{
if ( A[high].compareTo(pivot) >= 0 )
{
high--;
}
else
{
exch(A, low, high);
low++;
}
}
exch(A, s, high);
return high;
}
|
Finally, we (1) swap(pivot,A[high]) and (2) return high :
// partition(A, s, e): partition A[s]..A[e-1] using pivot A[s]
public static <T extends Comparable<T>> int partition(T[] A, int s, int e)
{
T pivot = A[s];
int low = s+1, high = e-1;
while (low <= high)
{
if ( A[high].compareTo(pivot) >= 0 )
{
high--;
}
else
{
exch(A, low, high);
low++;
}
}
exch(A, s, high); // A[s] = pivot
return high;
}
|
// Sort integers
public static void main(String[] args)
{
Integer[] A = { 5, 4, 1, 7, 2, 9, 3, 6 };
System.out.println("Input = " + Arrays.toString(A) + "\n");
QuickSort.sort(A, 0, A.length);
System.out.println("Output = " + Arrays.toString(A) + "\n");
}
|
DEMO: demo/14-sort/14-quick-sort/Demo.java + Demo2.java
The partition( ) method discussed in Liang's text book is as follows:
|
public static int partition(int[] list, int first, int last)
{
int pivot = list[first]; // Choose the first element as the pivot
int low = first + 1; // Index for forward search
int high = last - 1; // Index for backward search
while (low < high)
{
// Search forward from left
while (low <= high && list[low] <= pivot)
low++;
// Search backward from right
while (low <= high && list[high] > pivot)
high--;
// Swap two elements in the list
if (low < high)
{
int temp = list[high];
list[high] = list[low];
list[low] = temp;
}
}
// Adjust high to find the border
while (high > first && list[high] >= pivot)
high--;
// Swap pivot with list[high]
if (pivot > list[high])
{
list[first] = list[high];
list[high] = pivot;
return high;
}
else
{
return first; // Pivot was the smallest element...
}
}
|
|