本文介绍插入排序(Insertion sorts)算法的相关知识。
1 算法介绍
在插入排序中,数字列表可分为两个子列表:已排序的和未排序的,它们通过假想的一堵墙分隔开。
在排序过程中,将未排序子列表中第一个元素(按照数字升降顺序)插入到已排序子列表中合适的位置,再将假想的这堵墙(根据实际情况朝着对应方向)移动一个元素位置,这样每次排序后,已排序子列表中的元素将增加一个,同时未排序子列表中的元素将减少一个,每次把一个元素从未排序子列表移动到已排序子列表就完成了一轮排序。一个含有 n 个元素的数字列表需要 n-1 轮排序来完成数据的重新排列。
根据上述内容,可总结插入排序算法的一般解题步骤如下:
- 将假想墙放置在数字列表第一个元素的右侧,墙的左侧为已排序子列表,右侧为未排序子列表;
- 将未排序子列表中第一个元素插入到已排序子列表中合适的位置;
- 将假想墙向右移动一个位置;
- 反复执行2至3步操作,直至整个数字列表排序完成(需要 n-1 轮)。
2 示例代码及说明
插入排序算法的示例代码如下:
#include <stdio.h>
#include <stdlib.h>
int main()
{
/* 插入排序函数声明 */
int sort(int array[], int n);
int num[5] = {0};
int i = 0;
/* 接收用户输入的5个整型数 */
printf("please input 5 integer numbers: \n");
for (i = 0; i < 5; i++)
{
scanf("%d", &num[i]);
}
/* 使用插入排序对数组num从小到大进行排序 */
i = sort(num, 5);
/* 打印排序后的数字顺序 */
printf("the sorted numbers: \n");
for (i = 0; i < 5; i++)
{
printf("%d ", num[i]);
}
printf("\n");
return 0;
}
/*
* 插入排序法的函数定义
* 数组array存放待排序数字
* n表示数组array大小
*/
int sort(int array[], int n)
{
int i;
int j;
int tmp;
/* n个数字进行排序,共需要进行n-1轮比较 */
for (i = 1; i < n; i++)
{
/* 每次循环将未排序子列表中的第一个元素插入到已排序子列表中合适的位置 */
for (j = i; j > 0; j--)
{
if (array[j] < array[j - 1])
{
tmp = array[j];
array[j] = array[j - 1];
array[j - 1] = tmp;
}
}
}
return 0;
}
上述代码运行结果如下:
please input 5 integer numbers:
22 -21 0 89 100
the sorted numbers:
-21 0 22 89 100
说明:
- 在外层循环中,为变量 i 赋初始值“1”,可以更好地对应假想墙的初始位置(数字列表第一个元素的右侧)。同时,通过 i 的自增操作,使假想墙的位置从左向右移动;
- 在插入排序算法中,外层循环是从第二个元素开始进行排序操作的;而选择排序和冒泡排序是从第一个元素开始的,所以,插入排序的排序对象,是第2个元素至第n个元素;而选择排序和冒泡排序的排序对象,是第1个元素至第n-1个元素(即最后剩余的第n个元素不必考虑)。