1.冒泡排序:
时间复杂度 :
O(N^2), 与数据原始排列状态无关(即使原始数组已经排列好了,也是需要进行相同次数的操作)。
过程:
依次找出最大, 次大…放在arr[arr.length-1],arr[arr.length-2]…
代码实现:
public static void bubbleSort(int[] arr) {
if (arr == null || arr.length < 2) {
return;
}
for (int e = arr.length - 1; e > 0; e--) { // 0~e
for (int i = 0; i < e; i++) {
if (arr[i] > arr[i + 1]) {
swap(arr, i, i + 1);
}
}
}
}
private static void swap(int[] arr, int i, int j) {
arr[i] = arr[i] ^ arr[j];
arr[j] = arr[i] ^ arr[j];
arr[i] = arr[i] ^ arr[j];
}
2.插入排序:
时间复杂度 :
与数据原始排列状态有关:O(N)(如果原始数列已经排好序) O(N^2)(如果原始数列未排好序)
过程:
视为打牌时每抽一张牌插入到手上的牌堆中。
假设a=[7,6,5,8], 将其从小到大排列:
- 第0~0位[7]是有序的,无需交换, a=[7,6,5,8]
- 第0~1位[7,6]是无序的(因为将6和7进行比较,需要交换),交换完后a=[6,7,5,8], 此时第0~1位是有序的
- 第0~2位[6,7,5]是无序的(因为将5和7进行比较,需要交换), 交换完后a=[6,5,7,8]; 再将5和6进行比较, 需要交换, a=[5,6,7,8], 此时第0~2位是有序的
- 第0~3位[5,6,7,8]是有序(因为将8和7进行比较,无需交换), 此时第0~3位是有序的
代码实现:
public static void insertionSort(int[] arr) {
if (arr == null || arr.length < 2) {
return;
}
// 0~0已经有序, 此时要满足0~i有序
for (int i = 1; i < arr.length; i++) {
for (int j = i - 1; j >= 0 && arr[j] > arr[j + 1]; j--) {
swap(arr, j, j+1);
}
}
}
// i和j是一个位置的话会出错
public static void swap(int[] arr, int i, int j) {
arr[i] = arr[i] ^ arr[j];
arr[j] = arr[i] ^ arr[j];
arr[i] = arr[i] ^ arr[j];
}
3.选择排序:
时间复杂度 :
O(N^2), 与数据原始排列状态无关(即使原始数组已经排列好了,也是需要进行相同次数的操作)
过程:
第0位存放最小数,就要找arr[0~N-1]中的最小值
第1位存放次小数,就要找arr[1~N-1]中的最小值…
代码实现:
public static void selectionSort(int[] arr) {
if (arr == null || arr.length < 2) {
return;
}
for (int i = 0; i < arr.length; i++) { //i~N-1
int minIndex = i; // 假设第i位置上为最小的数
for (int j = i + 1; j < arr.length; j++) { //i~N-1上找最小值
minIndex = arr[j] < arr[minIndex] ? j : minIndex;
}
swap(arr, i, minIndex);
}
}
private static void swap(int[] arr, int i, int j) {
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
4.tips:
为什么在swap函数中可以运用该三行代码完成两个数的交换? 异或运算(^):可以理解为无进位相加,首先了解其两个性质:
(1) 0 ^ N = N且N ^ N = 0
(2)满足交换律(通过无进位相考虑,假设a=110,b=012,c=101,a^b^c的结果是对每一位进行无进位相加,与顺序无关)和结合律
假设 int a = 2, b = 3:
执行完第一句后, a = 2 ^ 3, b = 3
执行完第二句后, a = 2 ^ 3, b = 2 ^ 3 ^ 3 = 2 ^ (3 ^ 3) = 2 ^ 0 = 2
执行完第三句后, a = 2 ^ 3 ^ 2 = 2 ^ 2 ^ 3 = 0 ^ 3 = 3, b = 2 ,此时实现交换!
注意:在一个数组中如果i==j,是不能通过这三行代码实现arr[i]和arr[j]间的交换,只会使得两个位置上的值变为0