算法描述
首先举一个例子,类似于扑克牌的排序,比如我们手里有2和4,接下来又来一个3这时候我们的操作是直接吧3插入到2和4中间,这时候手里的牌就变成了2 3 4,那么在这个算法里大体思想也是一样的,插入算法基本上分三步。
- 找到插入元素。
- 找到合适插入位置。
- 插入元素,把插入位置之后的元素往后移一位。
代码思想讲解
首先我们把给定的序列分成有序区和无序区,但是因为计算机在循环之前不知道是不是有序的,所以在操作之前的计算机里把所有的数组元素都当做了无序区。
- 为什么a[0]没有储存元素?(监视哨的作用)
首先我们要知道在计算机里面要想交换两个变量的值必须依靠第三个变量来储存,否则就会造成数据丢失这里a[0]的作用和下面程序t的作用是一样的 。
#include<stdio.h>
int main()
{ int a=1,b=2,t;
printf("交换之前%d\t%d\n",a,b);
t=a;
a=b;
b=t;
printf("交换之后%d\t%d",a,b);
return 0;
}
结果
-
要用到两个循环。
首先在C语言里,有数组就一定有循环来对其进行相应的控制,这里因为的思想是从无序区挑选元素插入到有序区,所以,应该有两个循环,分别控制两个区域,第一层循环目的是从无序区选取要插入的元素,第二层循环目的是将要插入的元素依次从有序区的末尾一直比较到第一个元素直到找到合适的插入位置。 -
为什么程序刚开始把a[1]算入了有序区?
看下面的代码,程序在第一次执行循环的时候情况如下图所示。这里因为a[1]自己一个元素没有可比性,所以可以直接把他当成有序区,只不过只有一个元素而已。
在执行完第一次循环之后的情况是这样子的,找到合适的位置插入,有序区增加一个长度,无序区减少一个长度,依次类推,直到最后一个元素被插入到合适的位置整个序列也就成功的变成了有序序列
代码展示
#include<stdio.h>
#define N 5
void insert(int a[],int n)//直接插入排序函数
{ int i,j;
for(i=2;i<=n;i++)
{
a[0]=a[i];
for(j=i-1;j>0;j--)//已经排好序的序列
{
if(a[0]<a[j])//找到合适的插入位置
{ a[j+1]=a[j];
a[j]=a[0];
}
else//如果不用插入则直接进入有序区
break;
}
}
}
int main()
{ int a[N+1],i;//分配a[0]--a[11]十一个空间,a[0]作为储存需要交换数字的空间
printf("请输入十个无序的数字");
for(i=1;i<=N;i++)//a[1]--a[10]十个数字
scanf("%d",&a[i]);
insert(a,N);//引用函数对数组进行直接插入排序
printf("经过直接插入排序之后的序列是\n");
for(i=1;i<=N;i++)
printf("%d\t",a[i]);
return 0;
}