最近又新学了一种排序啦----直接插入排序
先看题目:
看见这个题目,我刚开始用的是选择排序,然后正确67%,所以我就去学了一下直接插入排序算法:先看本题直接插入排序代码:
#include<stdio.h>
int a[1001];
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n;
scanf("%d",&n);
int h;
for(int i=0; i<n; i++)
{
scanf("%d",&a[i]);
}
int k,j;
scanf("%d",&k);
for(int i=1; i<k+1; i++)
{
if(a[i-1]>a[i])
{
h=a[i];
for( j=i-1; j>=0&&a[j]>h; j--)
a[j+1]=a[j];
a[j+1]=h;
}
}
for(int i=0; i<n; i++)
printf("%d ",a[i]);
printf("\n");
}
return 0;
}
这篇文章共包含两个部分,包括对插入排序地理解和记忆和我写这道题的思路及错误更正。
对于插入排序,基本思路是:把一行整数看作是两份,一份是前面的,一份是后面的,注意:我们在这里把前面的看作已排好的序列(可以是一个或多个),后面的则为要插入的序列(一个)这里指的看作是每一步即每一循环看作哦!(具体理解可以看代码分析部分)然后每一步都要对一个数进行排序及找到合适的位置插入;等到最后一个数插入完毕后就完成了。
下面来分析一下代码我觉得难以理解的地方:这里的k指的是执行几步,即换几个数,k输入下面的循环指的是进行的步骤:注意了:这里为什么i是1,i<k+1呢?这是因为我们要记的是k步但是循环里面有i-1哦,若是不那么写的话那么i=0时,i-1又是什么呢?若是i=k时,i-1=k-1;就不能对最后一个数进行排序了;这也是我在写代码过程中忽略的,为什么结果是对的,那是这个例子的缘故,刚好凑巧罢了;而在这个循环里面有一个if语句,是判断如果前面的比后面的大,不是升序,就会执行循环里面的句子。即定义一个变量,让它等于靠后的数, 循环的表达式一即定义一个变量j让它等于刚刚序号及下标小的那个数字,从那开始依次往前遍历(你可以这么理解,这就符合了刚刚讲两部分的原理,因为我们刚开始比的是两个数而不是两部分东西,而在这个循环里面就开始把范围从前面一个数到一个范围。)为什么要往前遍历,这就对应了前面的原理中的在排好序的前面部分找后面那个数的位置(这里解释一下为什么前面是排好序了的,因为我们是刚开始的两部分是前面两个数排序,前面一部分只有一个数,是可以看作已经排好了的,而后面随着排好了的越来越多,我们总是把要排序的一个数看作一部分,前面排好的看作一部分。每排好一个数就把那个数插入相应位置,然后再找下一个数作为后一部分。)用图纸画一下条件里面的便于理解,以五个为例:
在这里总结一下记忆方法: 用大循环包小循环,大循环表示要比的数字的移动,而条件则是判断是否符合排序顺序,排序都要中间变量,把靠后的变量存在中间变量里面,往后遍历当然要在前一部分遍历,找到那个位置刚好大于要比的数,在这遍历中间的数都要往后移一位来为要插入的数空出位置,等所有的都移动完,最后一个满足它的j往后移一位的地方插入该数,这里举个例子:
虽然在这里中间变量还是有始有终,中间的东西还是变了味,因为这不是纯粹的交换。
最最最后,再热乎一下我对编程的热爱:甘心情愿乐得过这寂寞日子,才能有这寂寞日子中寻出真趣味,获得真光明的一日。