五、直接插入排序(平均时间复杂度:O(n^2))
1、介绍:直接插入排序属于内部排序法,是对欲排序的元素以插入的方式找寻该元素的适当位置,以达到排序的目的。
2、思想:把n个待排序列看成一个有序表和一个无序表,开始时有序表只含有一个元素(通常为第一个元素),无序表中含有第n-1个元素。在排序过程中,每次从无序表抽取一个元素,把它与有序表中的元素依次比较,将它插入有序表中的适当位置,使之成为有序表。
3、思路图:
4、代码如下:
public static void insertSort(int[] arr){
int insertVal = 0;
int insertIndex = 0;
for(int i = 1; i < arr.length; i++) {
//定义待插入的数
insertVal = arr[i];
insertIndex = i - 1; // 即arr[1]的前面这个数的下标
// 给insertVal 找到插入的位置
// 说明
// 1. insertIndex >= 0 保证在给insertVal 找插入位置,不越界
// 2. insertVal < arr[insertIndex] 待插入的数,还没有找到插入位置
// 3. 就需要将 arr[insertIndex] 后移
while (insertIndex >= 0 && insertVal < arr[insertIndex]) {
arr[insertIndex + 1] = arr[insertIndex];// arr[insertIndex]
insertIndex--;
}
// 当退出while循环时,说明插入的位置找到, insertIndex + 1
// 举例:理解不了,我们一会 debug
//这里我们判断是否需要赋值
if(insertIndex + 1 != i) {
arr[insertIndex + 1] = insertVal;
}
}
}
解释:当退出while循环后,说明已经给待插入的元素找到了插入位置,那为什么还要一个if语句判断呢?因为如果insertIndex + 1 = i,说明待插入的元素已经大于有序序列最大元素 ,此时不用再插入了。
六、希尔排序(平均时间复杂度:O(nlogn))
1、介绍:它是简单插入排序经过改进之后的一个更高效的版本,也称缩小增量排序。因为在简单插入排序算法中,当需要插入的数是较小的数时,有序表中后移的次数明显增多,对效率有些影响。
2、基本思想:希尔排序是按照一定增量对下标进行分组,对每组使用直接插入排序算法排序;通过对增量的缩小,每组包含的有序元素越来越多,当增量缩减至1时,整个序列被分为一组,算法完成。
3、思路图:
4、代码如下:
①在对有序序列插入时,使用交换法(使用交换法代价高)
public static void shellSort1(int[] arr){
int temp = 0;
int gap = arr.length / 2;
while (gap >= 1){
for(int i = gap ; i < arr.length; i++){
for(int j = i - gap; j >= 0; j -= gap){
if(arr[j] > arr[j + gap]){
temp = arr[j];
arr[j] = arr[j + gap];
arr[j + gap] = temp;
}
}
}
gap /= 2;
}
}
②在对有序序列插入时,使用位移法
public static void shellSort2(int[] arr){
//增量gap,并逐渐的缩小增量
for(int gap = arr.length / 2; gap > 0; gap /= 2){
for(int i = gap; i < arr.length; i++){
int j = i;
int temp = arr[j];
while (j - gap >= 0 && temp < arr[j - gap]){
arr[j] = arr[j - gap];
j -= gap;
}
arr[j] = temp;
}
}
}
七、简单选择排序(平均时间复杂度:O(n^2))
1、介绍:选择排序属于内部排序,是从待排序列中,按照指定的规则选出某一元素,再按照规定交换位置后达到排序的目的。
2、思想:第一次从arr【0】~arr【n-1】中选取最小值与arr【0】交换,第二次从arr【1】~arr【n-1】中选取最小值和arr【1】交换,第n-1次从arr【n-2】~arr【n-1】中选取最小值与arr【n-2】交换,总共进行n-1次,得到一个从小到大的有序序列。
3、思路:
4、代码如下:
private static void selectSort(int[] arr){
//算法先简单再复杂
for(int i = 0; i < arr.length - 1; i++){
int min = arr[i];
int minIndex = i;
for(int j = i + 1; j < arr.length; j++){
if(arr[j] < min){
min = arr[j];
minIndex = j;
}
}
if(minIndex != i){
arr[minIndex] = arr[i];
arr[i] = min;
}
}
}