基础排序(四)
来源:互联网 发布:启动sql server服务 编辑:程序博客网 时间:2024/06/01 07:56
希尔排序(Shell Sort)
算法思想:先将待排序表分割成若干个形如L[i, i+d, i+2d, … , i+kd]的“特殊”子表,分别进行插入排序,当整个表中元素已呈“基本有序”时,再对全体记录进行一次插入排序。
算法图解:
注:图片来自Lyndon的专栏,如若侵权请联系本人删除,谢谢!
基本代码如下:
template<typename T>void shellSort(T arr[], int n) { // Incremnet表示增量 int i, j, Increment; T tmp; // 增量变化 for (Increment = n / 2; Increment > 0; Increment /= 2) { // 在增量为某个值时,进行插入排序 for (i = Increment; i < n; ++i) { tmp = arr[i]; for (j = i; j >= Increment; j -= Increment) { if (tmp < arr[j - Increment]) arr[j] = arr[j - Increment]; else break; } arr[j] = tmp; } }}
为了和选择排序、插入排序、冒泡排序比较算法效率,故分别创建SelectionSort.h文件、InsertionSort.h和BubbleSort.h文件,并分别添加如下代码:
// SelectionSort.h#include <iostream>using namespace std;template<typename T>void selectionSort(T arr[], int n) { for (int i = 0; i < n - 1; i++) { // 寻找[i, n)区间里的最小值 int minIndex = i; for (int j = i + 1; j < n; j++) { if (arr[j] < arr[minIndex]) minIndex = j; } if (minIndex != i) swap(arr[i], arr[minIndex]); }}
// InsertionSort.h#include <iostream>using namespace std;template<typename T>void insertionSort(T arr[], int n) { for (int i = 1; i < n; i++) { // 寻找元素arr[i]合适的插入位置 T e = arr[i]; // j保存元素e应该插入的位置 int j; for (j = i; j > 0 && arr[j - 1] > e; j--) { arr[j] = arr[j - 1]; } arr[j] = e; }}
// BubbleSort.h#include <iostream>using namespace std;template<typename T>void bubbleSort(T arr[], int n) { for (int i = 0; i < n - 1; ++i) { // 表示本趟冒泡是否发生交换的标志 bool flag = false; for (int j = n - 1; j > i; --j) { if (arr[j - 1] > arr[j]) { swap(arr[j - 1], arr[j]); flag = true; } } // 本趟遍历后没有发生交换,说明已有序 if (flag == false) return; }}
好了,我们在main()中调用这几个算法比较一下它们的性能,具体代码如下:
int main(void) { int n = 10000; int *arr_1 = SortTestHelper::generateRandomArray(n, 0, n); int *arr_2 = SortTestHelper::copyIntArray(arr_1, n); int *arr_3 = SortTestHelper::copyIntArray(arr_1, n); int *arr_4 = SortTestHelper::copyIntArray(arr_1, n); SortTestHelper::testSort("Shell Sort", shellSort, arr_1, n); SortTestHelper::testSort("Insertion Sort", insertionSort, arr_2, n); SortTestHelper::testSort("Selection Sort", selectionSort, arr_3, n); SortTestHelper::testSort("Bubble Sort", bubbleSort, arr_4, n); delete[] arr_1; delete[] arr_2; delete[] arr_3; delete[] arr_4; return 0;}
其运行结果如下:
Shell Sort : 0.003 sInsertion Sort : 0.109 sSelection Sort : 0.245 sBubble Sort : 0.154 s
从结果中,我们发现希尔排序在随机数组的情况下,其运行效率比之前我们学习的排序算法的效率都高。那么我们不禁想问希尔排序在处理近乎有序的数据时,其效率也会这么高吗?为此,我们调用generateNearlyOrderdArray()来测试一下,其代码如下:
int main(void) { int n = 10000; int *arr_1 = SortTestHelper::generateNearlyOrderdArray(n, 100); int *arr_2 = SortTestHelper::copyIntArray(arr_1, n); int *arr_3 = SortTestHelper::copyIntArray(arr_1, n); int *arr_4 = SortTestHelper::copyIntArray(arr_1, n); SortTestHelper::testSort("Shell Sort", shellSort, arr_1, n); SortTestHelper::testSort("Insertion Sort", insertionSort, arr_2, n); SortTestHelper::testSort("Selection Sort", selectionSort, arr_3, n); SortTestHelper::testSort("Bubble Sort", bubbleSort, arr_4, n); delete[] arr_1; delete[] arr_2; delete[] arr_3; delete[] arr_4; return 0;}
其运行结果如下:
Shell Sort : 0.003 sInsertion Sort : 0.124 sSelection Sort : 0.187 sBubble Sort : 0.866 s
从结果中,我们发现希尔排序在处理近乎有序的数据时,仍然可以保证高效率。因此,我们在处理近乎有序的数据时,不仅推荐使用插入排序,也推荐希尔排序。
阅读全文
0 0
- 基础排序(四)
- PHP基础排序算法(四)快速排序
- mysql基础(字段排序四)
- 基础算法系列(四)——快速排序
- 【基础算法】排序-简单排序之四(Knuth洗牌算法)
- 算法与数据结构基础(四)高级排序算法1.归并排序
- 算法与数据结构基础(四)高级排序算法2.快速排序
- 基础算法之四--排序:之基数排序
- java基础入门之四(数组+排序)
- php四种基础排序算法
- C++基础笔记之四:插入排序
- php 四种基础排序算法
- 排序(四):堆排序
- 排序(四):希尔排序
- 排序系列(四)
- 选择排序(四)
- 归并排序(四)
- (四)排序
- (三)Angular4 英雄征途HeroConquest-初始化组件文件介绍
- 网络协议的综合思考 及 网络体系: OSI vs TCP/IP
- 总结:Distributed systems for fun and profit
- SSH面密码登陆设置失败一直需要输入密码可能原因分析
- Android 网络连接基本方式
- 基础排序(四)
- QTableView 数据操作
- TCP三次握手、四次握手过程,以及原因分析
- Angular2学习 Http通信
- keil中的头文件是放在哪个文件夹里的
- [PAT乙级]1019. 数字黑洞 (20)
- pat 1005. 继续(3n+1)猜想 (25)
- 蓝桥杯练习题 BEGIN-3 圆的面积
- 445. Add Two Numbers II(Java)