💻
正在更新中...
浅浅的整理一波排序算法,记录自己学的知识。
选择排序
选择排序是通过每次循环时找到一个最小的数放到相应位置上实现的。
分析
- 边界分析:
数组为空或者数组长度为1,则不需要排序。 - 逻辑分析:
已知 数组长度int N = arr.length
。
设定 数组结束位置索引下标int end = N-1
。- 第
1
次循环:从第0
位到第end
位选择最小的数,记录最小数下标索引minValueIndex
,将最小下标索引位置的数据放到第0
位。 - 第
2
次循环:从第1
位到第end
位选择最小的数,记录最小数下标索引minValueIndex
,将最小下标索引位置的数据放到第1
位。 - 第
3
次循环:从第2
位到第end
位选择最小的数,记录最小数下标索引minValueIndex
,将最小下标索引位置的数据放到第2
位。
… - 最后一次循环:从第
end-1
位到第end
位选择最小的数,记录最小数下标索引minValueIndex
,将最小下标索引位置的数据放到第end-1
位。
- 第
实现
private static void selectSort(int[] arr) {
// 数组长度
int N = arr.length;
// 遍历
for (int i= 0; i< N; i++) {
// 最小的数的下标
int minValueIndex = end;
// 找到最小的数
for (int j = i + 1; j < N; j++) {
minValueIndex = arr[j] < arr[minValueIndex] ? j : minValueIndex;
}
// 交换位置
HaUtil.swap(arr, i, minValueIndex);
}
}
冒泡排序
冒泡排序是通过数组相邻两个位置的数两两比较大小并交换顺序实现的。
分析
- 边界分析:
数组为空或者数组长度为1,则不需要排序。 - 逻辑分析:
已知 数组长度int length = arr.length
。
设定 数组结束位置索引下标int end = length-1
。-
第1次循环
- 比较
arr[0]
和arr[1]
大小并交换位置。 - 比较
arr[1]
和arr[2]
大小并交换位置。
… - 比较
arr[end-1]
和arr[end]
大小并交换位置。 - 此时
arr[end]
位置上的数一定是本次循环最大的数。
- 比较
-
第2次循环
- 比较
arr[0]
和arr[1]
大小并交换位置。 - 比较
arr[1]
和arr[2]
大小并交换位置。
… - 比较
arr[end-2]
和arr[end-1]
大小并交换位置。 - 此时
arr[end-1]
位置上的数一定是本次循环最大的数,小于等于上次循环得到的最大数。
- 比较
-
依次类推,每一次循环都能保证从后向前是有序的。
-
最终排序完成。
-
实现
private static void bubbleSort(int[] arr) {
int length = arr.length;
for (int end = length - 1; end >= 0; end--) {
// 0~1,1~2...end-1~end,在0-end这次循环中,两两比较将最大值移动到end位置上
for (int second = 1; second <= end; second++) {
if (arr[second - 1] > arr[second]) {
swap(arr, second - 1, second);
}
}
}
}
插入排序
插入排序是通过从0位置开始循环,每次累加1个索引位置,使这段局部范围内的数据有序(局部有序类似冒泡排序),循环完成最终实现全局有序。
分析
-
边界分析:
数组为空或者数组长度为1,则不需要排序。 -
逻辑分析:
已知 数组长度int length = arr.length
。
设定 数组结束位置索引下标int end = length-1
。
0 ~ 0
位置上天然有序,第1次循环从1位置开始即可。- 第
1
次循环 要保证0 ~ 1
位置上 局部有序。0 ~ 0
位置已经有序,只需要确定1
位置的数的大小顺序。- 如果
arr[0]
>arr[1]
则交换。
- 第
2
次循环 要保证0 ~ 2
位置上 局部有序。0 ~ 1
位置已经有序,只需要确定2
位置的数的大小顺序。- 如果
arr[1]
>arr[2]
则交换。 - 如果
arr[0]
>arr[1]
则交换。
- 第
3
次循环 要保证0 ~ 3
位置上 局部有序。0 ~ 2
位置已经有序,只需要确定3
位置的数的大小顺序。- 如果
arr[2]
>arr[3]
则交换。 - 如果
arr[1]
>arr[2]
则交换。 - 如果
arr[0]
>arr[1]
则交换。
…
- 第
end
次循环 要保证0 ~ end
位置上 局部有序。0 ~ end-1
位置已经有序,只需要确定end
位置的数的大小顺。arr[end-1]
>arr[end]
交换。
…- 如果
arr[2]
>arr[3]
则交换。 - 如果
arr[1]
>arr[2]
则交换。 - 如果
arr[0]
>arr[1]
则交换。
- 最终完成全局有序。
- 第
实现
public static void insertSort(int[] arr) {
if (arr == null || arr.length < 2){
return;
}
int N = arr.length;
for (int end = 1; end < N; end++) {
for (int pre = end - 1; pre >= 0 && arr[pre] > arr[pre + 1]; pre--) {
HaUtil.swap(arr, pre, pre + 1);
}
}
}
📒 整个小工具类
public class HaUtil {
// 打印
public static void printArray(int[] arr) {
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
System.out.println();
}
// 交换
public static void swap(int[] arr, int i, int j) {
int tmp = arr[j];
arr[j] = arr[i];
arr[i] = tmp;
😁 浅测一下
public static void main(String[] args) {
int[] arr = {2, 6, 6, 3, 1, 83, 34, 5, 7, 23, 0, 56, 3, 73, 5};
HaUtil.printArray(arr);
// selectSort(arr);
// bubbleSort(arr);
insertSort(arr);
HaUtil.printArray(arr);
}