直接插入排序
直接插入排序(straight insertion sort)是插入排序中最简单的排序算法,类似于玩纸牌时整理手中纸牌的过程。基本思想:依次将待排序序列中的每一个记录插入到一个已排好序的序列中,直到全部记录都排好序。
直接插入排序算法过程示例
代码示例
#include <iostream> using namespace std; int main() { int a[100] = {0}; int nm = 0; int j = 0; cin >> nm; for(int i = 1; i <= nm; i++) { cin >> a[i]; } for(int i = 2; i <= nm; i++) { a[0] = a[i]; for(j = i-1; j > 0 && a[0] < a[j]; j--) { a[j+1] = a[j]; } a[j+1] = a[0]; } for(int i = 1; i < nm; i++) { cout << a[i] << ' '; } return 0; }
希尔排序
希尔排序(shell sort)是对直接排序的一种改进,基本思想:先将整个待排序记录序列分割成若干个子序列,在子序列内分别进行直接插入排序,待整个序列基本有序时,再对全体记录进行一次直接插入排序。
(基本有序和局部有序不同,基本有序是指已接近正序,例如{1,2,8,4,5,6,7,3,9};局部有序只是某些部分有序,例如{6,7,8,9,1,2,3,4,5},局部有序不能提高直接插入排序算法的时间性能。)
希尔排序示例
第一趟,相隔5个长度的数(一般d = n/2)为一个子序列,如图(59,14)、(20,23)、(17,83)、(36,13)、(98,28)为子序列,在子序列内直接插入排序;
第二趟,相隔2个长度的数(一般d = d/2)为一个子序列,如图(14,17,28,23,36)、(20,13,59,83,98)为子序列,在子序列内直接插入排序;
第三趟,相隔1个长度的数(一般d = d/2)为一个子序列,在子序列内直接插入排序;
直接插入排序算法在记录个数较多时效率低,所以希尔排序不断减少间隔,多次使用直接插入排序算法,是对直接插入排序算法的改进。
子序列的构成不能是简单地"逐段分割",而是将相距某个"增量"的记录组成一个子序列,这样才有效地保证在子序列内分别进行直接插入排序后得到的结果是基本有序而不是局部有序。
代码示例
#include <iostream> using namespace std; int main() { int a[100] = {0}; int nm = 0; int d = 0, j = 0, i = 0; cin >> nm; for(int i = 1; i <= nm; i++) { cin >> a[i]; } for(d = nm/2; d >= 1; d = d/2) { for(i = d+1; i <= nm; i++) { a[0] = a[i]; for(j = i - d; j > 0 && a[0] < a[j]; j = j - d) { a[j+d] = a[j]; } a[j+d] = a[0]; } } for(i = 1; i <= nm; i++) { cout << a[i] << ' '; } return 0; }