插入排序
基本思想
把n个元素的数列分成有序(前)和无序(后)的两部分
{{a1},{a2,a3,a4,…,an}} {{a1⑴,a2⑴},{a3⑴,a4⑴ …,an⑴}} … {{a1(n-1),a2(n-1) ,…},{an(n-1)}}
每次处理就是将无序的数列中第一个元素与有序数列的元素从后到前比较,找到插入位置,将该元素插入到有序数列的适当的最终的位置上(稳定排序)。
参考代码一
#include <iostream> #include <cstdlib> using namespace std; void insertSort(int array[], int size) { for(int i = 1; i < size; ++i) { for(int j = i; j > 0 && array[j-1] > array[j]; --j) { int tmp = array[j]; array[j] = array[j-1]; array[j-1] = tmp; } } } int main() { int a[] = {1, 3, 5, 7, 8}; size_t size = sizeof(a) / sizeof(int); insertSort(a, size); for(int i = 0; i < size; ++i) cout << a[i] << " "; cout << endl; }
连续交换的时候相当于整体后移,把做比较元素放到最终位置上,修改如下。
参考代码二
#include <iostream> #include <cstdlib> using namespace std; void insertSort(int array[], int size) { for(int i = 1; i < size; ++i) { int tmp = array[i]; int j; for(j = i; j > 0 && array[j-1] > array[j]; --j) array[j] = array[j-1]; array[j] = tmp; } } int main(int argc, char **argv) { int a[] = {1, 3, 5, 7, 8}; size_t size = sizeof(a) / sizeof(int); insertSort(a, size); for(int i = 0; i < size; ++i) cout << a[i] << " "; cout << endl; }
运行结果
1 3 5 7 8
分析
空间:仅需要一个辅助空间,为O(1)
时间:对数列进行升序排列,最好情况——已经是升序了,比较次数为(n-1)次;最坏情况——已经是降序了,比较次数为(n-1)*n/2,赋值操作为(n-1)*n/2 + (n-1)。
平均来说插入排序算法复杂度为O(n2)。因而,插入排序不适合对于数据量比较大的排序应用。但是,如果需要排序的数据量很小,例如,量级小于千,那么插入排序还是一个不错的选择。 插入排序在工业级库中也有着广泛的应用,在STL的sort算法和stdlib的qsort算法中,都将插入排序作为快速排序的补充,用于少量元素的排序(通常为8个或以下)。