插入排序和希尔排序

最后更新于:2022-04-01 16:16:59

几种常见排序的动画演示:[常见排序的动画演示](http://www.cs.usfca.edu/~galles/visualization/flash.html)**** **插入排序**:由N-1趟排序组成,第i趟排序保证位置0到i-1上元素是已经排好序的。 在该算法代码实现中使用了可以减少元素交换次数的技巧:在for循环内,实现了数组元素移动而没有明显使用交换。将插入排序的搜索插入位置的过程和移动元素的过程合并一起进行,从而减少了元素交换次数。位置i上的元素存储在tmp中,而位置i之前的所有更大的元素都被向右移动一个位置;然后tmp被放置在正确的位置上。这个技巧与实现二叉堆和堆排序中所用的技巧相同(可以减少交换次数,加快速度),参考[二叉堆的插入删除等操作C++实现](http://blog.csdn.net/u013074465/article/details/42028473) 和 [堆排序](http://blog.csdn.net/u013074465/article/details/42043697)。 **注意:**这几处之所以可以使用该技巧是因为他们都是对数组的操作,通过下标来实现该技巧。 该算法的平均时间为O(N^2)。希尔排序是为了冲破二次时间的屏障,但是最终证明,其时间最坏情况为O(N^2),希尔增量对算法效率的影响很大。本文只给出了希尔排序的简单思路,没有涉及希尔增量的选取。 ~~~ /* 插入排序的C实现。 平均情形为O(N^2)。 一共进行n-1趟排序,第i趟排序时保证前i个(0到i-1)是排好序的 */ void InsertionSort(int array[], int n) { int i, j; int tmp; for (i = 1; i < n; i++) { /* 这里实现了数组元素移动而没有明显使用交换。 位置i上的元素存储在tmp中,而位置i之前的所有更大的元素 都被向右移动一个位置;然后tmp被放置在正确的位置上。 这个技巧与实现二叉堆所用的技巧相同(可以减少交换次数,加快速度)。 */ tmp = array[i]; for (j = i; j > 0 && array[j - 1] > tmp; j--) array[j] = array[j - 1]; array[j] = tmp; } } template<typename T> void ShellSort(vector<T>& unorder) { //希尔排序 int gap; int i; for (gap = unorder.size() / 2; gap > 0; gap /= 2) for (i = gap; i < unorder.size(); i++) { T tmp = unorder[i]; int j = i; for (; j >= gap && tmp < unorder[j - gap]; j -= gap) unorder[j] = unorder[j - gap]; unorder[j] = tmp; } } ~~~
';