希尔排序

希尔排序是对插入排序的改进。增加了分组

分组插入排序 降低元素个数,然后对每组分别进行插入排序
利用分组增量遍历,因为最后必须全部排序一次,然后分别对每组插入排序。把每组的第一个数作为有序序列,
要比较的第一个基准数就是第二个

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<random>
#include<time.h>
#include<sys/timeb.h>
using namespace std;
#define MAX 50000long getSystemTime()
{struct timeb tb;ftime(&tb);return tb.time * 1000 + tb.millitm;  //毫秒
}void printArr(int arr[], int length)
{for (int i = 0; i < length; i++){printf("%d ", arr[i]);}printf("\n");
}
//插入排序
void insertSort(int arr[], int length)
{int j;for (int i = 1; i < length; i++)  //从第二个数开始是无序队列。第一个数为有序队列{if (arr[i]<arr[i - 1]){int temp = arr[i];  //将满足条件的元素缓冲到temp中for (j = i - 1; j >= 0 && temp < arr[j]; j--)  //将有序数列分别遍历{arr[j + 1] = arr[j];}arr[j + 1] = temp;  //填补坑}}
}
//错误
void shellSortme(int arr[], int length)
{int increasement = length;//确定分组的增量increasement = increasement /3+1;int i, j, k;for (i = 0; i < increasement; i++)  //外层分组循环,最后等于1时全部再一起排列一次{for (j = i + increasement; j < length; j += increasement)  //从i+creasement是无序的第一个数{if (arr[i + increasement] < arr[i]){int temp=arr[i];for (k = i + increasement; k < j && arr[k] < temp; k -= increasement){arr[k] = arr[k + 1];}arr[k + 1] = temp;}}}
}void shellSort(int arr[], int length)
{int increasement = length;int i, j, k;do {//确定分组的增量increasement = increasement / 3 + 1;//外层分组循环,最后等于1时全部再一起排列一次for (i = 0; i < increasement; i++)  {//从i+creasement是无序的第一个数for (j = i + increasement; j < length; j += increasement)  {if (arr[j] < arr[j - increasement]){int temp = arr[j];//temp如果大于arr[k]的话,就不需要移动元素。//只有temp小于arr[k]即有序数组的其中一个数,才需要继续往前移动for (k = j - increasement; k >= 0 && temp<arr[k]; k -= increasement){arr[k + increasement] = arr[k];  //将满足条件有序的元素往后移动}arr[k + increasement] = temp;}}}} while (increasement > 1);
}int main()
{int arr[MAX];srand((unsigned int)time(NULL));  //种子for (int i = 0; i < MAX; i++){arr[i] = rand() % MAX;}//printf("未排序数组为:");//printArr(arr, MAX);long t_start = getSystemTime();shellSort(arr, MAX);long t_end = getSystemTime();//printf("希尔排序后数组为:");//printArr(arr, MAX);printf("希尔排序%d个元素,所需时间:%1d\n", MAX, t_end - t_start);system("pause");return 0;
}

运行结果:

快速排序

分治法加挖坑填数
找一个基准,小于放左边,大于放右边。一直遍历。填坑。
一般将第一数作为基准数。第一个数下标为i.挖坑。最后一个下标为j,从右边找一个数填坑。找到小于基准数的然后填坑。则此时j的位置就是坑了,此时从左往右找比基准数大的然后填坑。。。。此时i的地方为坑,继续一直循环下去,直到i==j时,把基准数填i位置的坑。然后此时i的位置是正确的,然后将i的左边和右边分别进行相同的操作。所以用到了递归i<j就是递归结束条件>

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<random>
#include<time.h>
#include<sys/timeb.h>
using namespace std;
#define MAX 50000long getSystemTime()
{struct timeb tb;ftime(&tb);return tb.time * 1000 + tb.millitm;  //毫秒
}void printArr(int arr[], int length)
{for (int i = 0; i < length; i++){printf("%d ", arr[i]);}printf("\n");
}void quickSortme(int arr[], int start, int end)
{int mid = (start + end) / 2;int temp = arr[start];int i = start;int j = end;if (i >= j){//从后往前比较,找一个比基准数小的数,放前面if (arr[j] < temp){arr[i] = arr[j];arr[j] = temp;j--;}//从前往后比较,找一个比基准数大的数,放后面if (arr[i] > temp){arr[i] = arr[j];arr[i] = temp;i++;}}
}
//快速排序,从小到大
void quickSort(int arr[], int start, int end)
{   int i = start;int j = end;int temp = arr[start];  //作为基准数if (i < j){while (i<j){//从右向左比较,找一个比基准数小的元素,放左边while (i < j && arr[j] >= temp)  //从右往左遍历,寻找满足小于基准数的元素{j--;}if (i<j) {arr[i] = arr[j];  //填左边坑i++;}//从左往右比较,找一个比基准数大的数,放右边while (i < j && arr[i] <= temp)  //从左往右遍历,寻找满足大于基准数的元素{i++;}if (i<j){arr[j] = arr[i];  //填右边坑j--;}}//把基准数放到i位置arr[i] = temp;//对左半部分进行快速排序quickSort(arr,start, i - 1);//对右半部分进行快速排序quickSort(arr, i+1, end);}
}int main()
{int arr[MAX];srand((unsigned int)time(NULL));  //种子for (int i = 0; i < MAX; i++){arr[i] = rand() % MAX;}//printf("未排序数组为:");//printArr(arr, MAX);long t_start = getSystemTime();quickSort(arr, 0,MAX-1);long t_end = getSystemTime();//printf("冒希尔排序后数组为:");//printArr(arr, MAX);printf("快速排序%d个元素,所需时间:%1d\n", MAX, t_end - t_start);system("pause");return 0;
}

结果:

归并排序

分组,然后排序,然后存到数组,然后覆盖原来

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<random>
#include<time.h>
#include<sys/timeb.h>
using namespace std;
#define MAX 50000long getSystemTime()
{struct timeb tb;ftime(&tb);return tb.time * 1000 + tb.millitm;  //毫秒
}void printArr(int arr[], int length)
{for (int i = 0; i < length; i++){printf("%d ", arr[i]);}printf("\n");
}int* CreateArr()
{srand((unsigned int)time(NULL));  //种子int* arr =(int *)malloc(sizeof(int)*MAX);for (int i = 0; i < MAX; i++){arr[i] = rand() % MAX;}return arr;
}
//合并算法  从小到大
void merge(int arr[], int start, int end, int mid, int *temp)
{int i_start = start;int i_end = mid;int j_start = mid + 1;int j_end = end;//表示辅助空间有多少个元素int length = 0;//合并两个有序序列while (i_start <= i_end && j_start <= j_end){if (arr[i_start] < arr[j_start]){temp[length] = arr[i_start];length++;i_start++;}else{temp[length] = arr[j_start];length++;j_start++;}}//i这个序列while (i_start <= i_end){temp[length] = arr[i_start];length++;i_start++;}//j这个序列while (j_start <= j_end){temp[length] = arr[j_start];length++;j_start++;}//将辅助空间数据覆盖原空间for (int i = 0; i < length; i++){arr[start+i]=temp[i];}
}//归并排序,将两个有序序列合并成一个有序序列   不会写
void mergeSort(int arr[], int start,int end,int *temp)
{if (start >= end){return;}int mid = (start + end) / 2;//左半边mergeSort(arr, start, mid, temp);//右半边mergeSort(arr, mid+1, end, temp);//合并merge(arr, start, end, mid, temp);}int main()
{int *arr = CreateArr();long t_start = getSystemTime();//申请辅助空间int* temp = (int *)malloc(sizeof(int)*MAX);mergeSort(arr, 0, MAX - 1,temp);long t_end = getSystemTime();printf("归并排序%d个元素,所需时间:%1d\n", MAX, t_end - t_start);/*free(temp);free(arr);*/system("pause");return 0;
}

运行结果:

归并排序示意图:

思路:

因为题目要求复杂度为O(nlogn),故可以考虑归并排序的思想。

归并排序的一般步骤为:

1)将待排序数组(链表)取中点并一分为二;

2)递归地对左半部分进行归并排序;

3)递归地对右半部分进行归并排序;

4)将两个半部分进行合并(merge),得到结果。

参考自https://blog.csdn.net/boguesfei/article/details/80413365

数据结构排序2-希尔,快速,归并排序相关推荐

  1. 数据结构 排序(希尔排序)

    //希尔排序法--插入排序升级版 #include<stdio.h> #include<stdlib.h> #include<string.h> #include& ...

  2. 【数据结构-排序】4.图解归并排序和基数排序

    归并排序 排序思想 归并排序就是将两个或两个以上的有序表组合成一个新的有序表 从代码结构来看,归并排序类似树的后序遍历 -- (参考快速排序,类似树的先序遍历) 归并排序算法分析 归并排序的时间复杂度 ...

  3. 【实战笔记】Java 算法与数据结构-排序(选择、插入、冒泡、希尔、归并、快速、堆)

    文章目录 基础排序算法O(n^2) 选择排序 插入排序及优化 冒泡排序及优化 希尔排序及优化 高级排序算法O(nlogn) 归并排序及优化 快速排序及优化 堆和堆排序 排序算法总结 本文为慕课网实战课 ...

  4. 【数据结构与算法】高级排序(希尔排序、归并排序、快速排序)完整思路,并用代码封装排序函数

    本系列文章[数据结构与算法]所有完整代码已上传 github,想要完整代码的小伙伴可以直接去那获取,可以的话欢迎点个Star哦~下面放上跳转链接 https://github.com/Lpyexplo ...

  5. 数据结构(八):排序 | 插入排序 | 希尔排序 | 冒泡排序 | 快速排序 | 简单选择排序 | 堆排序 | 归并排序 | 基数排序 | 外部排序 | 败者树 | 置换-选择排序 | 最佳归并树

    文章目录 第八章 排序 一.排序的基本概念 (一)什么是排序 (二)排序的应用 (三)排序算法的评价指标 (四)排序算法的分类 (五)总结 二.插入排序 (一)算法思想 (二)算法实现 (三)算法效率 ...

  6. 冒泡排序、插入排序、选择排序、希尔排序、堆排序、归并排序等常用排序算法的比较

    掌握好常用的排序算法,在实际的项目开发中可以节省很多的时间.每一种排序算法在执行的效率上是存在差别的,这些微小的时间差,也许在平常的联系当中感觉不到,但是涉及到数据量比较大或者是在资源比较紧张的系统中 ...

  7. C语言——十四种内部排序算法【直接插入排序-冒泡排序-选择排序-插入排序-希尔排序-归并排序-快速排序-堆排序-折半插入排序-二分查找-路插入排序-表插入排序-简单选择排序-直接选择排序-树形选择】

    目录: 一:插入排序 A:直接插入排序 1.定义: 2.算法演示 实例1: 3.基本思想 4.排序流程图 实例1: B:希尔排序 1.定义: 2.算法演示 实例2: C:其他插入排序 a:折半插入排序 ...

  8. 排序算法(冒泡排序、选择排序、插入排序、希尔排序、快速排序、归并排序、基数排序)

    排序也叫排序算法,排序是将一组数据,依指定的顺序进行排列的过程. 排序的分类: 1)内部排序:指将需要处理的所有数据都加载到内部存储器中进行排序. 2)外部排序:数据量过大,无法全部加载到内存中,需要 ...

  9. 10种排序算法比较(直接插入排序、希尔排序、冒泡排序、快速排序、简单选择排序、堆排序、归并排序、基数排序、折半插入排序、2路插入排序)

    本文(所有排序算法代码+综合比较代码)链接:https://download.csdn.net/download/qq_39932172/11217572 一.比较目的: 由于<数据结构> ...

  10. 数据结构排序算法 内部排序(冒泡、鸡尾酒、选择、简单插入、二分插入、快排、希尔、归并、堆排)C语言实现

    文章目录 排序 冒泡排序 鸡尾酒排序 选择排序: 简单插入排序: 二分插入排序 快速排序: 希尔排序: 归并排序: 堆排序: 排序 点击以下图片查看大图: 冒泡排序 1.比较相邻的元素,如果前一个比后 ...

最新文章

  1. Spring Boot 中 @EnableXXX 注解的驱动逻辑
  2. 面试官眼中的计算机水平,面试官最不喜欢的五句话,千万别说了
  3. mysql库存先进先出_sql 先进先出 库存
  4. 解决chrome和firefox flash不透明的方法
  5. @Transactional事务生效条件与样例
  6. bson json c语言,对比平台--JSON和BSON之间的区别
  7. 操作系统之进程管理:9、进程互斥的硬件实现方法
  8. sql执行组件是灰色的_如何分析SQL执行计划图形组件
  9. 切比雪夫距离(bzoj 3210: 花神的浇花集会)
  10. (翻译)Importing models-FBX Importer - Animations Tab
  11. ArcGIS 地类净面积计算工具
  12. 练字格子纸模板pdf_十字田字格模板空格40格-练字用书十字格a4打印版下载最新excel版-西西软件下载...
  13. XCode+gtest快速搭建接口测试工程
  14. nodejs无法下载puppeteer附带的chromium解决方案
  15. 微信高级群发之预览接口
  16. 计算机应用基础是背的吗,计算机应用基础Excel2003电子表格系统
  17. php发邮件 环境,PHP使用Pear发送邮件(Windows环境)
  18. Android 自定义ViewGroup 实战篇 - 实现FlowLayout
  19. 数据增强算法SMOTE的实验结果分析
  20. 如何将AE动画导出为json文件

热门文章

  1. 不改变原数组的一些方法
  2. c语言数组转置原理,为什么这个数组转置不对?
  3. html表头的标签,HTML 表头单元格标签
  4. Spring —— 容器内部逻辑
  5. oracle状态blocked,oracle 监听状态为BLOCKED
  6. law是什么的缩写_Lawyer和Attorney 有什么不同?
  7. stm32高级定时器 基础知识
  8. irobot擦地机器人故障_33款扫地机器人口碑:售价6350元的戴森口碑垫底,小米、科沃斯谁更好用?...
  9. java 易变变量_关于java:易变变量和其他变量
  10. 基于Echarts+HTML5可视化数据大屏展示—大数据管理平台中心(二)