《数据结构与算法分析:C语言描述》复习——第六章“排序”——希尔排序

2014.06.17 02:43

简介:

  希尔排序是插入排序的改进版。交换排序的目的,是通过交换,将逆序数降低为0。每交换一对相邻元素,逆序数变化为1。如果交换的元素不相邻,则逆序数的变化可能就大于1。希尔排序的思路,就是通过交换离得更远的两个元素,让逆序数更快地变为0(当然,并不总是管用)。

描述:

  我们定义一个间隔k,每隔k各元素选取一次,可以选出一个子数组。那么可以找出k个这样的子数组。对于每个子数组进行插入排序,这样的插入排序中,每交换一次减少的逆序数可能大于1,从而提高效率。但排序以后k个子数组之间没有进行比较,因此我们再选取另一个间隔k’,再来一轮。实际上,这样的间隔序列可以自己定义,只要合理即可。通过查资料可以找到前辈们总结的比较靠谱的间隔序列。一种简单直观的间隔序列,就是{n / 2, n / 4, n / 8, ..., 1}。这是明显的折半,但注意不要把顺序反过来。理由很明显:如果你一开始就选1作为间隔,那就是插入排序,剩余的间隔排序就没有意义了,效率自然也不会提高。关于希尔排序的复杂度,不一定是O(n^2),要根据选取的间隔序列来分析。

实现:

 1 // My implementation for shell sort.

 2 #include <iostream>

 3 #include <vector>

 4 using namespace std;

 5 

 6 void shellSort(vector<int> &v)

 7 {

 8     int n, i, j;

 9     int tmp;

10     int increment;

11     

12     n = (int)v.size();

13     for (increment = n / 2; increment > 0; increment /= 2) {

14         for (i = increment; i < n; ++i) {

15             tmp = v[i];

16             for (j = i; j >= increment && v[j - increment] > tmp; j -= increment) {

17                 v[j] = v[j - increment];

18             }

19             v[j] = tmp;

20         }

21     }

22 }

23 

24 int main()

25 {

26     vector<int> v;

27     int n, i;

28     

29     while (cin >> n && n > 0) {

30         v.resize(n);

31         for (i = 0; i < n; ++i) {

32             cin >> v[i];

33         }

34         shellSort(v);

35         for (i = 0; i < n; ++i) {

36             cout << v[i] << ' ';

37         }

38         cout << endl;

39     }

40     

41     return 0;

42 }

 

你可能感兴趣的:(数据结构与算法)