这是网上最常见的插入排序的动图,你能看出什么规律来吗?
(关于希尔排序,也是很相似,可以看上一篇内容《快速简单理解——希尔排序》)
看看你得出的规律是否跟我得出的规律一样?请往下看:
仔细看图,我们可以得出一个规律:
1红色框的元素,是最新的一个数,在这里我们不妨叫它a【i】,(i从0到n-1),并把它放在temp里。temp=a【i】;最下面我会讲讲为什么要把a【i】赋值给temp;为什么不能直接用a【i】来比较;
2temp元素每次都与前面的元素a【j】比较,这里我们用j代替(j=i-i)。
3当temp<a【j】时:a【j】就向后移动;由原来下标a【j】变成了a【j+1】。也就是a【j+1】=a【j】。并且一直比较。
4.直到temp>a【j】的时候,这个时候,a【j】不需要向后移动;这时候temp就直接插入到a【j】的后面,也就是a【j+1】。即a【j+1】=temp;
接下来我们一起来写代码吧:
public void cr(int a[],int n){
for(int i=0;i<n;i++){
int j=i-1;
int temp=a[i];//这是我们找出规律1
while(j>=0 && temp<a[j]){//temp不断地一直与前面的数a【j】作比较。这是规律3
a[j+1]=a[j];
j--;
}
a[j+1]=temp;//当temp>a【j】时,就把temp插入到a【j+1】里。这是规律4
}
}
这就是代码实现的效果
1.接下来,我来说说为什么不直接用a【i】来与a【j】比较;这样不是更方便打代码?看一下运行的结果:
为了能让大家看清楚a【i】的变化,我给代码加上输出的注释:也就是红色的框。可以更直观的看出它们的变化:
我们可以看到。在还没比较之前,a【i】还是原本的数值,但是变化之后
数组已经产生了变化,也就直接影响到了a【i】,所以比较后的a【i】已经不是原本的值;所以我们需要temp来装原来a【i】的值;
好了,就是这样。这样是不是很容易理解插入排序了?
我们就可以很清楚的了解到,它的时间复杂度是O(n^2),且稳定的,空间复杂度是O(1)。