关于插入排序,上网看了一下,解释原理和过程的文章很多,代码基本是C和C++,Java的看不到,根据自己的理解,自动动手写了一个:
package paixu;
import java.util.Arrays;
/**
* 插入排序
*/
public class ChaRu {
void chaRu(int[] arr){
int temp;
for (int i=1;i<arr.length;i++){//将第i个元素往前插入
temp=arr[i];
for (int j=i-1;j>=0 && arr[j]>temp;j--){//条件,必须是j>=0在前,arr[j]>temp在后,否则角标越界异常
//将第j+1个元素往前插一个位置
arr[j+1]=arr[j];
arr[j]=temp;
/**
* arr[j] = temp这一步,简洁了代码,可是跟直接插入排序的定义不太符合。定义里,在排序的过程
* 中是不会直接将temp赋值给arr[j]的,只有当arr[j-1]比temp小时,才会temp赋值给arr[j]。
* 如果arr[j-1]比temp大,那么给arr[j]这个位置赋值的,应该是arr[j-1]的值,而非temp。
* 这样操作,虽然简化了代码,但有违定义
*/
}
}
}
public static void main(String[] args) {
ChaRu test = new ChaRu();
int[] arr={1,-3,5,-7,9,-5,8,6,4,2,0};
test.ChaRu(arr);
System.out.println(Arrays.toString(arr));
}
}
为了应对这个“有违定义”这个问题,冥思苦想之后,对代码做了改良。如下:
void chaRu(int[] arr){
int temp;
for (int i=1;i<arr.length;i++){//将第i个元素往前插入
temp=arr[i];
int j=i-1;
while (j>=0){
if (arr[j]>temp){
//将第j个元素往后插一个位置
arr[j+1]=arr[j];
if (j==0)
arr[j]=temp;
}else{
arr[j+1]=temp;//这里其实是给arr[j]这个位置赋值,因为上一轮循环中,j--了
break;
}
j--;
}
}
}
从写法上看,它更符合定义,但是没有第一种简洁。
或许会有更优雅的写法,希望以后能想到...
20230517网上看到了更加简洁的写法:
void InsertSort(int[] arr) {
for (int i = 1; i < arr.length; i++) {
int end = i - 1;
int temp = arr[i];
while (end >= 0) {
if (temp < arr[end]) {
arr[end + 1] = arr[end];//挪动数组
end--;
} else {
break;//找到了要插入的点
}
}
arr[end + 1] = temp;
}
}
简洁是一种智慧!