一、选择排序
首先找到数组中最小的元素,其次将它和数组的第一个元素交换位置(如果第一个元素就是最小元素那么它就和自己交换),再次在剩下的元素中找到最小的元素,将它与数组的第二个元素交换位置。如此往复,直到将整个数组排序,这种方式叫选择排序。
public class Selection {
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;
}
public static void sort (Comparable[] a){
// 将a[]按升序排列
int N = a.length; // 数组长度
for (int i = 0; i < N; i++) {
//将a[i]和a[i+1..N]中最小的元素交换
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 isSorted(Comparable[] a) {
for (int i = 1;i < a.length;i++){
if (less(a[i],a[i - 1]))
return false;
}
return true;
}
private static void show(Comparable[] a) {
for (int i = 0;i < a.length;i++)
System.out.print(a[i] + " ");
System.out.println();
}
public static void main(String[] args) {
//从标准输入读取字符串,将它们排序并输出
String[] a = new String[]{"1","5","6","3","7","10","8","0","9","2","4"};
sort(a);
assert isSorted(a);
show(a);
}
}
二、插入排序
有一个已经有序的数据序列,要求在这个已经排好的数据序列中插入一个数,但要求插入后此数据序列仍然有序,这个时候就要用到一种新的排序方法——插入排序法,插入排序的基本操作就是将一个数据插入到已经排好序的有序数据中,从而得到一个新的、个数加一的有序数据,算法适用于少量数据的排序(百度百科)
public class Insertion {
private static boolean isSorted(Comparable[] a) {
for (int i = 1;i < a.length;i++){
if (less(a[i],a[i - 1]))
return false;
}
return true;
}
private static void show(Comparable[] a) {
for (int i = 0;i < a.length;i++)
System.out.print(a[i] + " ");
System.out.println();
}
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;
}
public static void sort (Comparable[] a){
// 将a[]按升序排列
int N = a.length; // 数组长度
for (int i = 0; i < N; i++) {
//将a[i]插入到a[i-1]、a[i-2]、a[i-3]...之中
for (int j = i;j > 0 && less(a[j],a[j-1]);j--){
exch(a,j,j-1);
}
}
}
public static void main(String[] args) {
//从标准输入读取字符串,将它们排序并输出
String[] a = new String[]{"1","5","6","3","7","10","8","0","9","2","4"};
sort(a);
assert isSorted(a);
show(a);
}
}
三、希尔排序
希尔排序是插入排序的一种又称“缩小增量排序”,是直接插入排序算法的一种更高效的改进版本。希尔排序是非稳定排序算法(百度百科)
package com.arithmetic;
public class Shell {
private static boolean isSorted(Comparable[] a) {
for (int i = 1;i < a.length;i++){
if (less(a[i],a[i - 1]))
return false;
}
return true;
}
private static void show(Comparable[] a) {
for (int i = 0;i < a.length;i++)
System.out.print(a[i] + " ");
System.out.println();
}
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;
}
public static void sort (Comparable[] a){
// 将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[i - 2*h],a[i - 3*h]...
for (int j = i;j >= h && less(a[j],a[j - h]);j -= h)
exch(a,j,j - h);
}
h = h/3;
}
}
public static void main(String[] args) {
//从标准输入读取字符串,将它们排序并输出
String[] a = new String[]{"1","5","6","3","7","10","8","0","9","2","4"};
sort(a);
assert isSorted(a);
show(a);
}
}
四、归并排序
归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。(百度百科)
4.1、自顶向下的归并排序
public class Merge {
private static Comparable[] aux; // 归并所需的辅助数组
private static boolean isSorted(Comparable[] a) {
for (int i = 1;i < a.length;i++){
if (less(a[i],a[i - 1]))
return false;
}
return true;
}
private static void show(Comparable[] a) {
for (int i = 0;i < a.length;i++)
System.out.print(a[i] + " ");
System.out.println();
}
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;
}*/
public static void sort (Comparable[] a){
aux = new Comparable[a.length]; // 一次性分配空间
sort(a,0,a.length - 1);
}
public static void sort (Comparable[] a,int lo,int hi){
// 将a[lo ... hi]排列
if (hi <= lo) return;
int mid = lo + (hi - lo)/2;
sort(a,lo,mid); // 将左半边排序
sort(a,mid + 1,hi) ; // 将右半边排序
merage(a,lo,mid,hi); // 归并结果
}
private static void merage(Comparable[] a, int lo, int mid, int hi) {
// 将a[lo ... mid] 和 a[mid + 1 ... hi] 归并
int i = lo,j = mid + 1;
for (int k = lo;k <= hi;k++) // 将a[lo ... hi]复制到aux[lo ... hi]
aux[k] = a[k];
for (int k = lo;k <= hi;k++) // 归并回到a[lo ... hi]
if (i > mid)
a[k] = aux[j++];
else if (j > hi)
a[k] = aux[i++];
else if (less(aux[j],aux[i]))
a[k] = aux[j++];
else
a[k] = aux[i++];
}
public static void main(String[] args) {
//从标准输入读取字符串,将它们排序并输出
String[] a = new String[]{"A","C","E","B","E","D","C","F","G","A","C"};
sort(a);
assert isSorted(a);
show(a);
}
}
4.2、自底向上的归并排序
public class MergeBU {
private static Comparable[] aux; // 归并所需的辅助数组
private static boolean isSorted(Comparable[] a) {
for (int i = 1;i < a.length;i++){
if (less(a[i],a[i - 1]))
return false;
}
return true;
}
private static void show(Comparable[] a) {
for (int i = 0;i < a.length;i++)
System.out.print(a[i] + " ");
System.out.println();
}
private static boolean less(Comparable v, Comparable w) {
return v.compareTo(w) < 0;
}
public static void sort (Comparable[] a){
// 进行lgN次两两归并
int N = a.length;
aux = new Comparable[N];
for (int sz = 1;sz < N;sz = sz + sz) // sz:子数组大小
for (int lo = 0;lo < N - sz;lo += sz + sz) // lo:子数组大小
merage(a,lo,lo + sz - 1,Math.min(lo + sz + sz - 1,N - 1));
}
private static void merage(Comparable[] a, int lo, int mid, int hi) {
// 将a[lo ... mid] 和 a[mid + 1 ... hi] 归并
int i = lo,j = mid + 1;
for (int k = lo;k <= hi;k++) // 将a[lo ... hi]复制到aux[lo ... hi]
aux[k] = a[k];
for (int k = lo;k <= hi;k++) // 归并回到a[lo ... hi]
if (i > mid)
a[k] = aux[j++];
else if (j > hi)
a[k] = aux[i++];
else if (less(aux[j],aux[i]))
a[k] = aux[j++];
else
a[k] = aux[i++];
}
public static void main(String[] args) {
//从标准输入读取字符串,将它们排序并输出
String[] a = new String[]{"A","C","E","B","E","D","C","F","G","A","C"};
sort(a);
assert isSorted(a);
show(a);
}
}
五、快速排序