排序算法
1、选择排序 SelectionSort
1.1 工作原理
找到未排序数组中最小的元素,放到初始位置,反复到数组末尾。
1.2 详细描述
- 第1步:找到数组下标0 ~ N-1 中最小数,与数组下标0的数交换位置。
- 第2步:找到数组1 ~ N-1 中最小数,与数组下标1的数交换位置。
- 第i步:找到数组 i-1 ~ N-1 中最小数,与数组下标i-1的数交换位置。
- 第N-1步:找到数组 N-2 ~ N-1 中最小数,与数组下标N-1的数交换位置。
1.3 动图
1.4 代码
public static void selectionSort(int[] arr) {
if (arr == null || arr.length < 2) {
return;
}
int N = arr.length;
for (int i = 0; i < N; i++) {
int minValueIndex = i;
for (int j = i + 1; j < N; j++) {
minValueIndex = arr[j] < arr[minValueIndex] ? j : minValueIndex;
}
swap(arr, i, minValueIndex);
}
}
2、冒泡排序 BubbleSort
2.1工作原理
从头两两比较相邻元素,将大的放到后者,反复到最大的元素到数组末尾。循环反复。每次元素像冒泡一样升到数组最后。
2.2详细描述
- 第1步,未排序数组下标范围:0 ~ N-1。
- 比较下标 i i+1 ,i大交换,i+1大不变。i 范围 0 ~ N-2
- 第2步,未排序数组下标范围:0 ~ N-2。
- 比较下标 i i+1 ,i大交换,i+1大不变。i 范围 0 ~ N-3
- 第j步,未排序数组下标范围:0 ~ N-j。
- 比较下标 i i+1 ,i大交换,i+1大不变。i 范围 0 ~ N-j-1
- 第N-1步,未排序数组下标范围:0 ~ 1。
- 比较下标 i i+1 ,i大交换,i+1大不变。i 范围 0 ~ 1
2.3 动图
2.4 代码
public static void bubbleSort(int[] arr) {
if (arr == null || arr.length < 2) {
return;
}
//0~n-1
//0~n-2
//0~n-3
//0~end
int N = arr.length;
for (int end = N - 1; end >= 0; end--) {
//0~end 做事
// 0 1 12 23 end-1end
for (int j = 0; j <= end - 1; j++) {
if (arr[j] > arr[j + 1]) {
swap(arr, j, j + 1);
}
}
}
}
3、插入排序 InsertSort
3.1工作原理
在有序的数组中,从后向前扫码到相应位置,插入新元素。
3.2 详细描述
-
第1步,0 ~ 0为有序数组,将下标为1的元素对有序数组从后向前依次比较插入。
-
第2步,0 ~ 1为有序数组,将下标为2的元素对有序数组从后向前依次比较插入。
- 下标2与下标1比较,下标1小交换,下标2小不变。
-
第i步,0 ~ i-1为有序数组,将下标为i的元素对有序数组从后向前依次比较插入。
- 下标 i 与下标 i-1 比较,下标 i 小交换,下标 i-1 小不变。
- 下标 i-1 与下标 i-2 比较,下标 i-1 小交换,下标 i-2 小不变。
- …
- 直到新的元素左边没有元素,或者左边的元素小于新元素
-
第N步,0 ~ N-2为有序数组,将下标为N的元素对有序数组从后向前依次比较插入。
3.3 动图
3.4 代码
public static void insertSort1(int[] arr) {
if (arr == null || arr.length < 2) {
return;
}
//0~1
//0~2
//0~n-1
int N = arr.length;
for (int end = 1; end < N; end++) {
int newNumIndex = end;
while (newNumIndex - 1 >= 0 && arr[newNumIndex - 1] > arr[newNumIndex]) {
swap(arr, newNumIndex, newNumIndex - 1);
newNumIndex--;
}
}
}
//相较第一种 优化后等效 代码更简洁
public static void insertSort2(int[] arr) {
if (arr == null || arr.length < 2) {
return;
}
//0~1
//0~2
//0~n-1
int N = arr.length;
for (int end = 1; end < N; end++) {
//pre 新数的前一个位置 end-1 end
for (int pre = end - 1; pre >= 0 && arr[pre] > arr[pre + 1]; pre--) {
swap(arr, pre, pre + 1);
}
}
}