1,找到数组中最小的元素。
2,将其与第一个元素交换位置(如果第一个元素就是最小元素,就和其本身交换)。
3,在剩下的元素中找到最小的元素。
4,将其与第二个元素交换位置。
5,遍历。
public class Selection
{
public static void sort(Comparable[] a)
{
int N = a.length;
for (int i = 0; i < N; i++)
{
//将a[]按升序排列
int min = i;
for (int j = i+1; j < N; j++)
if (less(a[j], a[min])) min = j;
exch(a, i, min);
}
}
private static boolean less(Comparable v, Comparable w)
{ return v.compareTo(w) < 0; }
private static void exch(Comparable[] a, int i, int j)
{ Comparable t = a[i]; a[i] = a[j]; a[j] = t; }
}
2,插入排序
过程:
1,将第二个元素与第一个元素比较。
2,如果第二个元素比第一个小,则交换位置。否则,不交换位置。
3,将第三个元素与第二个元素比较。
4,如果第三个元素比第二个小,则交换。否则,不交换位置。
5,再将第二个元素与第一个元素比较。
6,重复步骤1,2。
7,遍历。
代码:
public class Insertion
{
public static void sort(Comparable[] a)
{
int n = a.length;
for (int i = 1; i < N; i++)
{
for (int j = i; i > 0 && less(a[j], a[j-1]; j--))
exch(a, j, j-1);
}
}
}
使数组中任意间隔为h的元素都是有序的。
1,引入间隔int h = 1,根据数组的长度,取合适的h值:while(h < N/3) h=3*h+1;
2,令h = h/3,while(h >= 1),对数组进行间隔为h的插入排序。
3,最后h一定等于1,进行间隔为1的插入排序。完成。
public class Shell
{
public static void sort(Comparable[] a)
{
int N = a.length;
int h = 1;
while (h < N/3) h = 3*h + 1;
while (h >=1)
{
//将数组变h有序
for (int i = h; i < N; i++)
{
//将a[i]插入到a[i-h], a[j-2*h], a[j-3*h]...之中
for (int j = i; j >= h && less(a[j], a[j-h]); j -= h)
exch(a, j, j-h);
}
h = h/3;
}
}
}
1,排序左边。
2,排序右边。
3,合二为一。
4,递归调用步骤1,2,3。
public class Merge
{
private static Comparable[] aux;
public static void sort(Comparable[] a)
{
aux = new Comparable[a.length];
sort(a, 0, a.length-1);
}
private static void sort(Comparable[] a, int lo, int hi)
{
if (hi <= lo) return;
int mid = lo + (hi - lo)/2;
sort(a, lo, mid);
sort(a, mid+1, hi);
merge(a, lo, mid, hi);
}
public static void merge(Comparable[] a, int lo, int mid, int hi)
{
int i = lo, j = mid +1;
for (int k = lo; k <= hi; k++)
if (i > mid) a[k] = aux[j++]; //左半边用尽(取右半边的元素)
else if (j > hi) a[k] = aux[i++]; //右半边用尽(取左半边的元素)
else if (less(aux[i], aux[i])) a[k] = aux[j++]; //右半边的当前元素小于左半边的当前元素(取右半边的元素)
else a[k] = aux[i++]; //右半边的当前元素大于等于左半边的当前元素(取左半边的元素)
}
}
1,随意取a[lo]作为切分元素。
2,从数组的左端开始向右扫描直到找到一个大于等于它的元素。
3,从数组的右端开始向左扫描直到找到一个小于等于它的元素。
4,交换它们的位置。
5,如此继续。当两个指针相遇时,将切分元素a[lo]和左子数组最右端的元素a[j]交换,然后返回j。
public class Quick
{
public static void sort(Comparable[] a)
{
StdRandom.shuffle(a); //消除对输入的依赖。需要导入DIY的jar包。
sort(a, 0, a.length -1);
}
private static void sort(Comparable[] a, int lo, int hi)
{
if (hi <= lo) return;
int j = partition(a, lo, hi);
sort(a, lo, j-1);
sort(a, j+1, hi);
}
private static int partition(Comparable[] a, int lo, int hi)
{
int i = lo, j = hi + 1;
Comparable v = a[lo];
while (true)
{
while (less(a[++i], v)) if (i == hi) break;
while (less(v, a[--j])) if (j == lo) break;
if (i >= j) break;
exch(a, i, j);
}
exch(a, lo, j);
return j;
}
}