排序算法 - Java实现
快速排序
最经典实现,worst case为O(n2)O(n2)。但随机化后最坏情况也能达到O(nlog(n))O(nlog(n))。
在这里提一下二叉搜索树(BST),它与快速排序有着民曲同工之妙。
比如:对6,10,13,5,8,3,2进行排序
快排,以6为key,小于6的放到左边,其他放到右边
| 6 | 10 | 13 | 5 | 8 | 3 | 2 |
|---|---|---|---|---|---|---|
| i,ji,j | ||||||
| 6 | 10 | 13 | 5 | 8 | 3 | 2 |
| ii | ||||||
| 6 | 5 | 13 | 10 | 8 | 3 | 2 |
| ii | ||||||
| 6 | 5 | 3 | 10 | 8 | 13 | 2 |
| ii | ||||||
| 6 | 5 | 3 | 2 | 8 | 13 | 10 |
| ↑↑ | ↑↑ | |||||
| 2 | 5 | 3 | 6 | 8 | 13 | 10 |
BST版本:比6小的都放到了左子树,其他的都放到了右子树。
6
/ \
5 8
/ \
3 13
/ /
2 10
快排的代码实现
package Algorithm;
import java.util.Arrays;
public class QuickSort {
public static void main(String[] args) {
QuickSort qs = new QuickSort();
int[] array = new int[]{3, 8, 4, 2, 6, 11, 13, 6};
System.out.printf("before: %s\n", Arrays.toString(array));
qs.quicksort(array);
System.out.printf("after: %s\n", Arrays.toString(array));
}
public void quicksort(int[] array) {
quicksort(array, 0, array.length);
}
private void quicksort(int[] array, int from, int to) {
if (from >= to - 1) {
return;
}
int key = array[from];
int i, j;
for (i = from, j = from + 1; j < to; j++) {
if (array[j] < key) {
swap(array, ++i, j);
}
}
swap(array, from, i);
quicksort(array, from, i);
quicksort(array, i + 1, to);
}
private void swap(int[] array, int i, int j) {
int tmp = array[i];
array[i] = array[j];
array[j] = tmp;
}
} /*
输出结果
before: [3, 8, 4, 2, 6, 11, 13, 6]
after: [2, 3, 4, 6, 6, 8, 11, 13]
*/
堆排序(heapsort)
调整根结点为最大值(最大堆),然后把根结点的值与数组最后的值交换,并在逻辑上将数组的长度减一,重构最大堆,如此循环往复,直到遍历完最后一个元素。
代码实现
package Algorithm;
import java.util.Arrays;
public class HeapSort {
public static void main(String[] args) {
HeapSort heapSort = new HeapSort();
int[] test = new int[]{7, 8, 5, 9, 3, 2, 6};
System.out.printf("before: %s\n",Arrays.toString(test));
System.out.printf("after: %s\n",Arrays.toString(heapSort.heapsort(test))); }
public void adjust(int[] left, int i, int len) {
int lChild = 2 * i + 1;
int rChild = 2 * i + 2;
int max = i;
if (i < len) {
if (lChild < len && left[lChild] > left[max])
max = lChild;
if (rChild < len && left[rChild] > left[max])
max = rChild;
if (i != max) {
swap(left, i, max);
adjust(left, max, len);
}
}
}
public int[] heapsort(int[] unsorted) {
for (int i = (unsorted.length) / 2 - 1; i >= 0; i--) {
adjust(unsorted, i, unsorted.length - 1);
}
for (int i = unsorted.length - 1; i > 0; i--) {
swap(unsorted, 0, i);
adjust(unsorted, 0, i);
}
return unsorted;
}
public void swap(int[] target, int i, int j) {
int tmp = target[i];
target[i] = target[j];
target[j] = tmp;
}
}/*
输出结果
before: [7, 8, 5, 9, 3, 2, 6]
after: [2, 3, 5, 6, 7, 8, 9]
*/
插入排序(insertion sort)
插入排序假设前i - 1个元素已经排好序,然后把第i个元素“插入”到适当的位置。
插排的代码实现
import java.util.Arrays;
import java.util.Comparator;
public class InsertionSort {
public <T extends Comparable> T[] sort_asc(T[] array, Comparator<T> cmp) {
int len = array.length;
T key;
for (int i = 1; i < len; i++) {
key = array[i];
int j = i - 1;
while (j >= 0 && cmp.compare(array[j], key) > 0) {
array[j + 1] = array[j];
j--;
}
array[j + 1] = key;
}
return array;
}
public static void main(String[] args) {
InsertionSort is = new InsertionSort();
Integer[] array = new Integer[]{5, 2, 4, 6, 1, 3,};
Comparator<Integer> cmp = Comparator.naturalOrder();
System.out.println(Arrays.toString(is.sort_asc(array, cmp)));
}
} /* Output:
[1, 2, 3, 4, 5, 6]
*/
归并排序
现在我们有两叠扑克牌,正面朝上,并且每一叠扑克牌都是排好序的,牌堆顶部的牌最小。现在我们要把这两叠扑克牌合成一叠,使之正面朝下放置,我们只需要把两个牌堆顶的牌比较一下,每次取较小的,如此往复,因为每次都是取最小的牌,所以最终得到的合并的牌堆也是排好序的。
public int[] mergesort(int[] array) {
try {
mergesort(array, 0, array.length);
} catch (NullPointerException e) {
throw new RuntimeException(e);
}
return array;
}
private void mergesort(int[] array, int p, int r) {
if (p < r - 1) {
int q = (p + r) / 2;
mergesort(array, p, q);
mergesort(array, q, r);
merge(array, p, q, r);
}
}
private void merge(int[] array, int p, int q, int r) {
int n1 = q - p;
int n2 = r - q;
int[] left = new int[n1 + 1], right = new int[n2 + 1];
System.arraycopy(array, p, left, 0, n1);
System.arraycopy(array, q, right, 0, n2);
left[n1] = Integer.MAX_VALUE;
right[n2] = Integer.MAX_VALUE;
int i = 0, j = 0;
for (int k = p; k < r; k++) {
if (left[i] <= right[j])
array[k] = left[i++];
else
array[k] = right[j++];
}
}

1054

被折叠的 条评论
为什么被折叠?



