1、插入排序
public static void insertionSort(int[] a) {
for (int i = 1; i < a.length; i++) {
int j;
int temp = a[i];
for (j = i; j > 0 && temp < a[j - 1]; j--) {
a[j] = a[j - 1];
}
a[j] = temp;
}
}
2、希尔排序
选择不同的增量序列会有不同的复杂度,有n的3/2,4/3,6/5次方等复杂度
public static void shellSort(int[] a) {
for (int gap = a.length >> 1; gap > 0; gap >>= 1) {
for (int i = gap; i < a.length; i++) {
int j;
int temp = a[i];
for (j = i; j >= gap && temp < a[j - gap]; j -= gap) {
a[j] = a[j - gap];
}
a[j] = temp;
}
}
}
3、堆排序
public static int[] sort(int[] a) {
for (int i = a.length >> 1; i >= 0; i--)
percDown(a, i, a.length - 1);
for (int i = a.length - 1; i > 0; i--) {
int temp = a[i];
a[i] = a[0];
a[0] = temp;
percDown(a, 0, i - 1);
}
return a;
}
public static void percDown(int[] a, int i, int n) {
int temp = a[i];
for (int child = i; (child << 1) + 1 <= n; i = child) {
child = (i << 1) + 1;
if (child + 1 <= n && a[child] < a[child + 1])
child++;
if (temp < a[child])
a[i] = a[child];
else
break;
}
a[i] = temp;
}
3、归并排序
public static void mergeSort(int[] a, int[] tempArray, int left, int right) {
if (left >= right)
return;
int mid = ((right - left) >> 1) + left;
mergeSort(a, tempArray, left, mid);
mergeSort(a, tempArray, mid + 1, right);
merge(a, tempArray, left, mid + 1, right);
}
public static void merge(int[] a, int[] tempArray, int leftPos, int rightPos, int rightEnd) {
int current = leftPos;
int leftStart = leftPos;
int rightStart = rightPos;
while (leftStart <= rightPos - 1 && rightStart <= rightEnd) {
if (a[leftStart] > a[rightStart])
tempArray[current++] = a[rightStart++];
else
tempArray[current++] = a[leftStart++];
}
while (leftStart <= rightPos - 1)
tempArray[current++] = a[leftStart++];
while (rightStart <= rightEnd)
tempArray[current++] = a[rightStart++];
for (int i = leftPos; i <= rightEnd; i++)
a[i] = tempArray[i];
}
4、快速排序
T(n) = 2T(n/2) + n,nlogn
public static void quickSort(int[] a, int low, int high) {
if (low >= high)
return;
int pivot = partition(a, low, high);
quickSort(a, low, pivot - 1);
quickSort(a, pivot + 1, high);
}
public static int partition(int[] a, int low, int high) {
int key = a[low];
while (low < high) {
while (a[high] >= key && high > low)
high--;
a[low] = a[high];
while (a[low] <= key && high > low)
low++;
a[high] = a[low];
}
a[low] = key;
return low;
}
5、快速选择 O(n)
public static void quickSelect(int[] a, int low, int high, int k){
if(low >= high) return;
int mid = partition(a, low, high);
if(k == mid + 1)
return;
if(k <= mid)
quickSelect(a, low, mid - 1, k);
else
quickSelect(a, mid + 1, high, k);
}
6、桶排序
适用于小正整数的排序,需要知道元素上界,O(n)
7、外部排序
多路归并:N个顺串构造完毕后,k路合并需要logk N趟
替换选择:用于构造归并顺串的算法,可以构造大小是内存两倍的顺串。先用全部内存构造堆,输出堆顶的数字进入顺串,再读入一个数,如果比堆顶大则加入堆,如果比堆顶小就将堆的大小减一(因为这个数可能比刚输出的数小,把这个数放在堆的最后一位,将堆大小减一)。这样每次有一个数出堆,有0.5个数进堆,最后堆大小为0,顺串长度的期望值是内存大小的两倍。