基础原始快速排序(进行了优化,保持了稳定性)
import edu.princeton.cs.algs4.StdOut;
import edu.princeton.cs.algs4.StdRandom;
public class QuickSort {
private int[] a;
public QuickSort(int N)
{
a = new int[N];
for (int i = 0; i < N; ++i)
a[i] = StdRandom.uniform(-15 * N,15 * N);
}
public QuickSort(int[] b)
{
a = new int[b.length];
for (int i = 0; i < a.length; ++i)
a[i] = b[i];
}
public int partition(int lo,int hi)
{
int i = lo,j = hi + 1;
int v = a[lo];
while (true)
{
while (a[lo] >= a[++i]) if (i == hi) break;
while (a[lo] <= a[--j]) if (j == lo) break;
if (i >= j) break;
int temp = a[j];
a[j] = a[i];
a[i] = temp;
}
int temp = a[j];
a[j] = a[lo];
a[lo] = temp;
return j;
}
public void sort(int lo,int hi)
{
if (hi <= lo) return;
int get = partition(lo,hi);
sort(lo,get - 1);
sort(get + 1,hi);
}
public void sort()
{
sort(0,a.length - 1);
}
public void display()
{
for (int i = 0; i < a.length; ++i)
StdOut.print(a[i] + " ");
StdOut.println();
}
}
小数组时快速排序比插入排序慢,再次优化
import edu.princeton.cs.algs4.StdOut;
import edu.princeton.cs.algs4.StdRandom;
public class QuickAndInsert {
private int[] a;
public QuickAndInsert(int N)
{
a = new int[N];
for (int i = 0; i < N; ++i)
a[i] = StdRandom.uniform(-15 * N,15 * N);
}
public QuickAndInsert(int[] b)
{
a = new int[b.length];
for (int i = 0; i < a.length; ++i)
a[i] = b[i];
}
public int partition(int lo,int hi)
{
int i = lo,j = hi + 1;
while (true)
{
while (a[lo] >= a[++i]) if (i == hi) break;
while (a[lo] <= a[--j]) if (j == lo) break;
if (i >= j) break;
int temp = a[i];
a[i] = a[j];
a[j] = temp;
}
int temp = a[lo];
a[lo] = a[j];
a[j] = temp;
return j;
}
public void InsertSort(int lo,int hi)
{
for (int i = lo; i < hi; ++i)
{
int j = i + 1;
int temp = a[j];
while (j > lo && temp < a[j - 1])
{
a[j] = a[j - 1];
--j;
}
a[j] = temp;
}
}
public void sort(int lo,int hi)
{
if (hi <= lo) return;
if (hi - lo <= 5)
{
InsertSort(lo,hi);
return;
}
int get = partition(lo,hi);
sort(lo,get - 1);
sort(get + 1,hi);
}
public void sort()
{
sort(0,a.length - 1);
}
public void display()
{
for (int i = 0; i < a.length; ++i)
StdOut.print(a[i] + " ");
StdOut.println();
}
}
重复元素过多,会将重复元素数组也切分未免太过浪费,再次进行优化,此次优化的排序方法成为 三向切分的快速排序
import edu.princeton.cs.algs4.StdOut;
import edu.princeton.cs.algs4.StdRandom;
public class Quick3Way {
private int[] a;
public Quick3Way(int N)
{
a = new int[N];
for (int i = 0; i < N; ++i)
a[i] = StdRandom.uniform(-15*N,15*N);
}
public Quick3Way(int[] b)
{
a = new int[b.length];
for (int i = 0; i < a.length; ++i)
a[i] = b[i];
}
public void sort(int lo,int hi)
{
if (lo >= hi) return;
int le = lo,i = lo + 1,he = hi;
int v = a[lo];
while (i <= he)
{
if (v > a[i])
{
int temp = a[le];
a[le++] = a[i];
a[i++] = temp;
}
else if (v < a[i])
{
int temp = a[i];
a[i] = a[he];
a[he--] = temp;
}
else
++i;
}
sort(lo,le - 1);
sort(he + 1,hi);
}
public void sort()
{
sort(0,a.length - 1);
}
public void display()
{
for (int i = 0; i < a.length; ++i)
StdOut.print(a[i] + " ");
StdOut.println();
}
}