插入排序:将n个待排序的元素看成一个有序和无序表,第一个元素认定就是有序的,后面的元素一一插入,插入的时候与排序过的元素进行比较放入合适的位置
int arr[]={3,4,2,1,5}
首先认定第一个元素就是有序的, 未排序表中的元素一一插入,与排序表中的元素比较放入合适的位置
3 | 4 ,2 ,1, 5
3 , 4 | 2 , 1 , 5
2 , 3 , 4 | 1 , 5
1 , 2 , 3 , 4 | 5
1 , 2 , 3 , 4 , 5 |
代码实现:还是每次的过程都先写出来:
我们具体做了什么呢?
首先确定要插入的数值,第一个元素默认就在有序序列中了,所以是从第二个元素的位置考虑插入有序序列中的 : int insertvalue = arr[1];
然后我们还得确定arr[1]前面的数是什么,可能刚开始想的是arr[0],但是这样不太好,因为后面我们做的是将待插入的数与有序列中的所有数进行比较
假设现在不是arr[1],而是arr[3]等待插入,他的前面还有3个数,我们定义了一个变量接受arr[2],那arr[1]和arr[0]怎么比较,
如果是设置索引待插入的数前面的索引: int insertindex = 2 (3-1)
我们通过index--还可以取得前面数的下标,arr[insertindex]这样就可以表示arr[1]和arr[0]了
public class InsertSort {
public static void main(String[] args) {
int arr[]={101,23,115,1};
InsertSort insertSort = new InsertSort();
insertSort.insertsort(arr);
}
public void insertsort(int arr[]) {
//首先开始应该是这样的{(101),23,115,1}
//第一轮下来=>{(23,101),115,1}
int insertindex = 0;// 这是arr[i]前面数的下标
int insertvalue = arr[1];
//给insertvalue找到插入的位置
while (insertindex >= 0 && insertvalue < arr[insertindex]) {
arr[insertindex + 1] = arr[insertindex];
//insertindex--是因为还需要和有序队列中前面的元素进行比较大小
insertindex--;
//如果insertindex已经是0了,这时候减一变成了-1,跳出循环
//下面我们还需要insertindex+1,才能使用
}
//如果insertvalue < arr[insertindex]这个条件就不满足,说明我们要插入的值比有序列中的
//数都要大
//退出while循环的时候,说明找到了插入的位置,但是跳出的时候insertindex被减去了1
//我们还需要加上一才是真正的索引
arr[insertindex+1]=insertvalue;
System.out.println("第一次排序"+Arrays.toString(arr));
insertindex=1;
insertvalue=arr[2];
while(insertindex >=0&& insertvalue<arr[insertindex]){
arr[insertindex+1]=arr[insertindex];
insertindex--;
}
arr[insertindex+1]=insertvalue;
System.out.println("第二次排序"+Arrays.toString(arr));
insertindex=2;
insertvalue=arr[3];
while(insertindex >=0&& insertvalue<arr[insertindex]){
arr[insertindex+1]=arr[insertindex];
insertindex--;
}
arr[insertindex+1]=insertvalue;
System.out.println("第三次排序"+Arrays.toString(arr));
}
}
根据前面的规率,变化的就是登待插入的值,我们把这个变化放进循环里面,得到最终的结果:
public void insertsort(int arr[]) {
for(int i=1;i<arr.length;i++){
insertvalue=arr[i];
insertindex=i-1;
while(insertindex >=0&& insertvalue<arr[insertindex]){
arr[insertindex+1]=arr[insertindex];
insertindex--;
}
//如果插入的位置正好在有序序列的后面就不用在赋值操作了
if(insertindex+1!=i){
arr[insertindex+1]=insertvalue;
}
}
System.out.println("插入排序"+Arrays.toString(arr));
}
}
测试方法怎么样:
public class InsertSort {
public static void main(String[] args) {
int arr[]={101,23,115,1};
InsertSort insertSort = new InsertSort();
insertSort.insertsort(arr);
}
}
最后看一下运行时间:
public class InsertSort {
public static void main(String[] args) {
int arr[]=new int[80000];
for(int i=0;i<80000;i++){
arr[i]=(int)(Math.random()*8000000);
}
Date date = new Date();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String time = simpleDateFormat.format(date);
System.out.println("排序前的时间:"+time);
InsertSort insertSort = new InsertSort();
insertSort.insertsort(arr);
Date date1 = new Date();
SimpleDateFormat simpleDateFormat1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String time2 = simpleDateFormat1.format(date1);
System.out.println("排序前的时间:"+time2);
}
}
尝试了几次都是0~1s,非常快
80000大小的数组,相同范围取随机数
冒泡排序是10s左右
选择排序是2~3s