终于等到你!!!
如果你想学习直接插入排序,那就进正文吧!
怎么理解
怎么实现
以直接插入排序:数组array[10 5 2 1 4]为例:
根据动图:想要用直接插入排序把array按从小到大顺序排好,实现的大致思路就是:
把第一个数10作为一块整体,把第二个数5作为插入数,把他们两进行排序。排好了[5 10 2 1 4]。
把前两个数5 10 作为一块整体,把第三个数2作为插入数,把他们三进行排序。排好了[2 5 10 1 4]。
把前三个数2 5 10 作为一块整体,把第四个数1作为插入数,把他们三进行排序。排好了[1 2 5 10 4]。
把前四个数1 2 5 10 作为一块整体,把第五个数4作为插入数,排好了[ 1 4 2 5 10 ]
接下来思考:如何把array的第一个数10作为一块?再把第二个数5插进来?
直接从array下标为1的位置开始操作,int i = 1 开始遍历数组,i每++一次,就会把数组分为左边已经排序好的一整块和右边要插入的数i。
把下标为i位置的5作为插入数,5比10小,把5插到10的前面
5比10小,怎么表示i位置前面的数?int j = i-1
怎么进行直接插入排序:
如果array[i]比array[j]大,那说明这一小块是排好序的,直接i++,开始新一轮直接插入排序。
先申请一块内存tmp保存5
如果array[i]比array[j]小,5<10,然后把j位置的值10放到i位置。
然后j --。
如果 j --后j=-1,把5插到array[j+1]位置。
显然把直接在10前面插入5后,j–就等与-1了,此时把5插入到array[j+1]即可。
int tmp = array[i];
array[i] = array[j];
j–;
当j–后,j==-1的时候,array[j+1] = tmp;
能走到这一步,说明第一组直接插入排序就完成了,此时i++,开始新一轮直接插入排序。
在这一轮我们就会面对:j – 不等于-1的情况。
把2通过直接插入排序插到5的前面:
先申请一块内存tmp保存2(2要和后面的5,和10都要比较,所以要先申请内存保存array[i]) 。
如果array[i]比array[j]小,2<10,然后把j位置的值10放到i位置。
然后j --。
此时j – 不等于-1:
继续比较array[i]和array[j]的大小,
如果array[i]小,把j位置的值填入array[j+1]位置,继续j–。
i – = -1或tmp里的值大于array[j+1],把tmp里存的插入数array[i]插到array[j+1]位置。
根据上面的思考过程,自己尝试写出代码吧!
参照代码(java)
import java.util.Arrays;
public class Main {
public static void insertSort(int[] array){
for (int i = 1; i < array.length ; i++) {
int tmp = array[i];
int j = 0;
for (j = i-1; j > -1; j--) {
if(tmp < array[j]){//如果是<=,该排序就变成了不稳定排序
array[j+1] = array[j];
}else{
break;
}
}
array[j+1] = tmp;
}
}
public static void main(String[] args) {
int[] arr = {10,5,2,1,4};
insertSort(arr);
System.out.println(Arrays.toString(arr));
}
}
分析时间复杂度,空间复杂度,排序稳定性
直接插入排序的时间复杂度有最好情况和最坏情况。最好情况就是数组元素完全有序时,例如给数组[1 2 3 4 5 6 ]排序,直接插入排序的时间复杂度就是O(n)。最坏情况就是数组元素完全逆序时,直接插入排序的时间复杂度就是O(n^2)。直接插入排序的特点就是:当所给的数据越有序,直接插入排序就越快。即使是我们所熟知的快排,最快的时候时间复杂度也达不到O(n)。
直接插入排序的空间复杂度是O(1)。
直接插入排序是稳定排序。一个本身就是稳定的排序,是可以实现为不稳定的排序的。但是相反,一个本身就不稳定的排序,是不可能实现为稳定排序的。
创作不易,如果帮助到您,感谢您的点赞支持!