九大排序之——插入排序
来源:互联网 发布:网络舆论论文 编辑:程序博客网 时间:2024/06/04 20:11
直接插入排序:
思想:
将要排序的序列看成两个序列,一个是有序序列,另一个是无序序列,每次取无序序列中的元素往有序序列中的合适位置插入,直到无序序列为空,排序完成。
图解示例(红色为有序序列黑色为无序序列)
执行步骤:
(1)一个数可以认为是有序的,所以第一次区间划分如上图;
(2)在无序序列中取一个数,从有序序列的最后一个数开始向前扫描,若该元素大于前一个元素则插入该位置;
(3)重复执行(2);
(4)待无序序列为空时排序完成。
代码实现:
#include<iostream>#include<assert.h>using namespace std;template<class T>void Print(const T* a, size_t n){for (size_t i = 0; i < n; ++i){cout << a[i] << " ";}cout << endl;}template<class T>struct Less//升序{bool operator()(const T& l, const T& r){return l < r;}};template <class T>struct Great//降序{bool operator()(const T& l, const T& r){return l > r;}};template<class T,class Compare>void InsertSort(T* a, size_t n)//插入排序{assert(a);for (size_t i = 1; i < n; ++i){int end = i - 1;//end用来保存有序区间的最后一个数据的位置T temp = a[i];//temp用来保存无序区间的第一个数据,也是即将要插入有序区间的数据while (end >= 0){if (Compare()(temp, a[end]))//利用仿函数实现比较{a[end + 1] = a[end];//为temp[i]留出合适的位置end--;}elsebreak;}a[end+1] = temp;//将temp插入到合适的位置}}void TestInsertSort(){int a[] = { 3, 5, 7, 2, 4, 1, 9, 8, 6 };InsertSort<int, Less<int>>(a, sizeof(a) / sizeof(a[0]));//升序Print(a, sizeof(a) / sizeof(a[0]));InsertSort<int, Great<int>>(a, sizeof(a) / sizeof(a[0]));//降序Print(a, sizeof(a) / sizeof(a[0]));}template<class T,class Compare>void ShellSort(T* a,size_t n){assert(a);int gap = n;while (gap > 1){gap = gap / 3 + 1;//+1是为了最后一次对全体数据进行插入排序for (size_t i = gap; i < n; i++){int end = i - gap;T tmp = a[i];while (end >= 0){if (Compare()(tmp, a[end])){a[end + gap] = a[end];end = end - gap;}elsebreak;}a[end + gap] = tmp;}}}void TestShellSort(){int a[] = { 2, 5, 4, 9, 3, 6, 8, 7, 1, 0 };ShellSort<int, Less<int>>(a, sizeof(a) / sizeof(a[0]));Print(a, sizeof(a) / sizeof(a[0]));ShellSort<int, Great<int>>(a, sizeof(a) / sizeof(a[0]));Print(a, sizeof(a) / sizeof(a[0]));}template<class T,class Compare>void SelectSort(T* a, size_t n){assert(a);for (size_t i = 1; i < n; ++i){int minIndex = i;//未排序区间的最小数据下标int start = i - 1;//未排序区间的第一个数据下标//选出第二部分最小数据for (size_t j = i + 1; j < n - 1; ++j)//用i+1来不断的缩小j的范围{if (Compare()(a[j + 1], a[minIndex]))swap(a[j + 1], a[minIndex]);elsebreak;}//第二部分最小数据和第三部第一个数据进行比较if (Compare()(a[minIndex], a[start]))swap(a[minIndex], a[start]);}}void TestSelectSort(){int a[] = { 2, 5, 4, 9, 3, 6, 8, 7, 1, 0 };SelectSort<int, Less<int>>(a, sizeof(a) / sizeof(a[0]));Print(a, sizeof(a) / sizeof(a[0]));SelectSort<int, Great<int>>(a, sizeof(a) / sizeof(a[0]));Print(a, sizeof(a) / sizeof(a[0]));}
运行结果:
复杂度与稳定性分析:
最坏时间复杂度:O(n^2)序列处于逆序或基本逆序的情况下
最好时间复杂度:O(n)序列有序或基本有序的情况下
空间复杂度:O(1)
稳定性:稳定
阅读全文
0 0
- 九大排序之——插入排序
- 九大排序之——基数排序
- 九大排序之——希尔排序
- 九大排序之——冒泡排序
- 九大排序之——堆排序
- 九大排序之——选择排序
- 九大排序之——快速排序
- 九大排序之——归并排序
- 九大排序之——计数排序
- 三大基础排序之——插入排序
- 排序——插入排序之直接插入排序
- 排序算法—插入排序之直接插入排序
- 十大排序算法之插入排序
- 算法之排序——插入排序
- 算法——排序之插入排序
- 八大排序之——插入排序
- 算法基础之排序—插入排序
- 十大排序算法之(四)——插入排序
- WebBrowser介绍——Javascript与C++互操作
- java实现牛牛算法
- 深入理解JavaScript系列(42):设计模式之原型模式
- 2017前端面试题
- qduoj 80 树结构重逢(树形DP)
- 九大排序之——插入排序
- 数据库锁机制
- 深入理解JavaScript系列(43):设计模式之状态模式
- 网络编程基础
- C# 如何在编译时将 dll 复制到 bin\Release 目录下
- Unity3d设计模式之单例模式
- Datagrid里面如何捕获前一页下一页最后页最前页的事件?
- 深入理解JavaScript系列(44):设计模式之桥接模式
- Openssh移植到Android系统的步骤