例22 插入排序
问题描述
排序是计算机程序设计中的一种重要操作,它的功能是将一个数据元素或记录的任意序列,重新排列成一个以关键字递增(或递减)排列的有序序列。
排序的方法有很多,简单插入排序就是一种简单的排序算法。
插入排序的基本思想是顺序将一个待排序的记录按其关键字值的大小插入到一个有序的序列中,插入后该序列仍然是有序的。
简单插入排序是一种最简单的排序方法。它的排序过程为:先将待排序序列中第1个记录看成是一个有序的子序列,然后从第2个记录起依次逐个地插入到这个有序的子序列中去。这很像玩扑克牌时一边抓牌一边理牌的过程,抓一张牌就插入到其应有的位置上去。
简单插入排序的排序过程如下图1所示。图1中方括号[ ]中为已排好序的记录关键字的子序列,下划线的关键字表示当前插入到有序子序列中的记录。
图1 简单插入排序的排序过程示例
编写一个程序,用简单插入排序方法将输入的N个整数按从小到大的顺序排列输出。
输入格式
第一行是一个正整数N (1 ≤ N ≤ 100000),代表数组中元素的个数。
第二行有N个整数,表示待排序的N个数组元素。
输出格式
一行,有N个整数,这N个整数按从小到大的顺序排列输出。
输入样例
10
7 2 5 4 9 6 3 10 1 8
输出样例
1 2 3 4 5 6 7 8 9 10
(1)编程思路。
将整个数组(n个元素)看成是由有序的(a[0],…,a[i-1])和无序的(a[i],…,a[n-1])两个部分组成;初始时i等于1,每趟排序时将无序部分中的第一个元素a[i]插入到有序部分中的恰当位置,共需进行n-1趟,最终使整个数组有序。
排序操作是一个二重循环,外循环控制排序趟数(1~n-1),内循环在有序部分中寻找当前元素a[i]的插入位置。
(2)源程序。
#include
#define N 50001
int main()
{
int a[N];
int n,i;
scanf("%d",&n);
for (i=0;i
scanf("%d",&a[i]);
for (i=1; i
{
int t=a[i];
int j= i-1;
while (j>=0 && t
{
a[j+1] = a[j];
j--;
}
a[j+1] = t;
}
for (i=0;i
printf("%d ",a[i]);
printf("\n");
return 0;
}
上面介绍了简单插入排序,下面再介绍两种简单的排序算法:直接选择排序法和冒泡排序法。
(3)直接选择排序。
直接选择排序也是一种比较简单的排序方法,它的排序过程为:先从待排序的所有记录中选出关键字最小的记录,把它与原始序列中的第一个记录交换位置;然后再从去掉了关键字最小的记录的剩余记录中选出关键字最小的记录,把它与原始序列中第二个记录交换位置;依次类推,直至所有的记录成为有序序列。直接选择排序的排序过程如图2所示。图中方括号[ ]中为已排好序的记录关键字的子序列,下划线的关键字表示它对应的记录对需要交换位置。
图2 直接选择排序的排序过程示例
编写一个程序,用直接选择排序方法将输入的十个整数按从小到大的顺序排列输出。
1)编程思路。
直接选择排序的过程是一个二重循环,外循环(i)控制排序趟数(0~n-2),内循环(j)寻找序列a[i]~a[n-1]中的最小者。
寻找一个序列最小值的方法是:先假定序列的第一个元素是最小值,然后将序列的第2个元素至最后一个元素依次和这个最小值比较,如果某个元素比最小值要小,则最小值就是这个元素。
2)源程序。
#include
#define N 50001
int main()
{
int a[N];
int n,i,j,k;
scanf("%d",&n);
for (i=0;i
scanf("%d",&a[i]);
for (i=0;i
{
k=i;
for (j=i+1;j
if (a[j]