虽然下午写了一篇博客,但是基于排序算法确实简单易懂,于是就趁着深夜简单介绍下插入排序~
插入排序是将指定的数据插入到已经排序好的数列中,举一个简单的小例子:
相信大家都打过扑克牌,在整理扑克牌时,对扑克牌进行排序,就是将待排序的扑克牌一张张地与已经整理好的扑克牌进行比较,在找到合适的位置时直接将牌插入其中即可。
下面以具体的数字进行演示:
数列初始化:
第一次将3插入,此时默认数列开头的8是有序区:
第二次将下标为2的1插入到有序区:
第三次将5插入到有序区:
第四次将2插入到有序区:
第五次将下标为5的 1插入到有序区:
最终结果:
插入排序的基本思想就是上流程图所示,注意每次插入的时候要将待插入的数据提取出来用另一个变量单独保存起来,再用这个变量与有序区的数据进行比较,不能直接用数组中的数据进行比较,比如第三次插入时,将A[3]保存到一个变量v中,之后再用v与有序区中的1,3,8进行比较。
这样做的主要原因就是在每次比较时,如果待插入的数大于有序区中的数时,那么久要将该数向后挪一位,这样就会将原先数组中的数据覆盖,这时如果我们还用原来的数组中的待插入的数进行与有序区的数据进行比较时就会产生错误。
对于插入排序,我原来还一直有一个下标方面的问题,就是有序区中即将与待插入数进行比较的数的下标j的确定。
一开始下标肯定为待插入数的前一个数下标,也就是有序区中的最后一个,在不断比较,不断挪位后,j不断减小,在挪位结束后,j 这时代表的是刚好找到小于等于带插入数的有序区中数的下标,而此时要注意A[j+1]=A[j+2],因为A[j+2]是上一次待插入数v与A[j+1]比较后从A[j+1]复制挪位过来的。
例如在上图第三次排序还未插入时,j=1,指向有序区的3,此时A[j+2]=A[j+1]=8。
所以在找到合适的位置后,直接将待插入数据v插入到下标为j+1的地方即可。
以下是具体的代码:
#include<stdio.h>
void Insertion_Sort(int A[],int N)
{
for(int i=1;i<N;i++)
{
int v=A[i]; //A[i]为当前要进行比较并插入的数据
int j=i-1; // j为当前与要插入数据进行比较的元素的下标,是不断更新的
while(j>=0 && A[j]>v)
{
A[j+1]=A[j];
j--;
}
A[j+1]=v;
}
}
int main()
{
int N;
int A[100];
scanf("%d",&N);
for(int i=0;i<N;i++)
scanf("%d",&A[i]);
Insertion_Sort(A,N);
for(int i=0;i<N;i++)
printf("%d ",A[i]);
return 0;
}
PS:在找了大量的画图软件后,还是感觉微软自带的画图工具和PPT中的画图工具简单够用~也不早了,睡了