冒泡排序(dubbo sort)
/**
* 冒泡排序
*
* @param arr
*/
public void dubboSort(int[] arr) {
boolean sort; // 标志位,如果为false,则代表,上一次循环中没有发生进行交换操作,说明所有元素已经正确排序,因此后面也没有交换的必要
int len = arr.length;
do {
sort = false;
for (int i = 0; i < len - 1; i++) {
if (arr[i] > arr[i + 1]) {
int temp = arr[i];
arr[i] = arr[i + 1];
arr[i + 1] = temp;
sort = true;
}
}
len--; // 避免已经排序的再做判断
} while (sort);
}
在冒泡排序过程中,第一轮,操作0~len-1
的元素,只是交换相邻的两个元素,直到将最大的元素通过交换传递到最后arr[len-1]
(以递增排序为例)。
然后再排序0~len-2
的元素,…以此类推。
选择排序(select sort)
/**
* 选择排序
* 有两个循环遍历,一个范围是:0~len;另一个范围是:i+1~len;每一次遍历只改变当前最小元素的下标的索引值
*
* @param arr
*/
public void selectSort(int[] arr) {
int len = arr.length;
for (int i = 0; i < len; i++) {
int minIndex = i;
for (int j = minIndex + 1; j < len; j++) {
if (arr[minIndex] > arr[j]) {
minIndex = j;
}
} // 循环结束,minIndex中保存的是本次(i+1 ~ len-1)中最小元素的下标值
if (minIndex != i) {
int temp = arr[minIndex];
arr[minIndex] = arr[i];
arr[i] = temp;
}
}
}
以将数组按照递增排序为例,则先把arr[0],作为最小的元素,循环遍历1~len-1,找到本轮遍历最小的元素的下标值,然后与arr[0]交换。
然后在从arr[1]开始,重复上面的操作。
插入排序(insert sort)
/**
* 插入排序
* 循环变量之前保持有序,将新元素逐一比较,并插入到有序列
* 1. 在数组已经有序的情况下,算法的时间复杂度为:O(n)
* @param arr
*/
public void insertSort(int[] arr) {
int len = arr.length;
for (int i = 0; i < len - 1; i++) {
if (arr[i] > arr[i + 1]) { // 这里的判断是必要的!!
for (int j = i + 1; j > 0; j--) {
if (arr[j - 1] > arr[j]) {
int temp = arr[j];
arr[j] = arr[j - 1];
arr[j - 1] = temp;
} else {
break;
}
}
}
}
}
快速排序(quick sort)
/**
* 快速排序
* 采用分治思想,将待排序的数组分为:arr[p,q-1] arr[q] arr[q+1,r]三部分
*
* @param arr
*/
public void quickSort(int[] arr, int p, int r) {
int q;
if (p < r) {
q = partition(arr, p, r);
quickSort(arr, p, q - 1);
quickSort(arr, q + 1, r);
}
}
/**
* 快速排序辅助函数
*
* @param arr arr[p, r]
* @param p 待排序数组的首个元素的下标
* @param r 待排序数组的最后一个元素的下标
* @return
*/
private int partition(int[] arr, int p, int r) {
int x = arr[r]; // 术语将arr[r]称作“主元”
int i = p - 1;
for (int j = p; j < r; j++) {
if (arr[j] <= x) {
i++;
int temp = arr[j];
arr[j] = arr[i];
arr[i] = temp;
}
}
int temp = arr[i + 1];
arr[i + 1] = arr[r];
arr[r] = temp;
return i + 1;
}
快速排序,效率最好的情况下,则是分为n/2
和n/2-1
,此时的时间复杂度为:nlog(n)
。
推荐
https://www.cs.usfca.edu/~galles/visualization/ComparisonSort.html
可以先看一遍算法的执行流程,然后再自己尝试编码O_o。