文章目录

  • 1、插入排序
    • 1.1直接插入排序
    • 1.2折半插入排序
    • 1.3希尔排序
  • 2、交换排序
    • 2.1冒泡排序
    • 2.2快速排序
  • 3、选择排序
    • 3.1简单选择排序
    • 3.2堆排序
  • 4、归并排序
  • 5、基数排序

1、插入排序

1.1直接插入排序

直接插入排序:每次将当前元素按照其大小插入到前面已有序的子序列中。

//arr[0~n-1]存数据;
void InsertSort(int arr[], int n){int i, j, temp;//遍历数组for (i = 1; i < n; i++){//当前元素的前驱大于当前元素if (arr[i - 1] > arr[i]) {temp = arr[i];  //保存arr[i]//将前面有序序列中的所有大于arr[i]的值全部后移一位for (j = i - 1; j >= 0 && arr[j] > temp; j--){arr[j + 1] = arr[j];}arr[j + 1] = temp;  //将原arr[i]赋值给arr[j + 1]}//if}//for
}

1.2折半插入排序

折半插入排序:与折半查找类似,逐一遍历数组元素,在数组前面有序的序列中找到该元素的位置

void InsertSort(int arr[], int n) {int i, low, high, mid;//用arr[1~n]存数,arr[0]保存当前元素,将arr[1]视为有序;for (i = 2; i<=n; i++) {  arr[0] = arr[i];  //初始化low和high指针分别为第一个元素和第i - 1个元素low = 1;high = i - 1;//循环直到low > high,查找当前元素在当前序列中的位置while (low <= high) {mid = (high + low) / 2;  //更新mid//mid指向的元素小于arr[0],去左半边继续排序if (arr[0] < arr[mid])     high = mid - 1;//mid指向的元素大于等于arr[0],去右半边,这是该算法稳定的原因else low = mid + 1;}//从arr[high+1]或arr[low]元素统一后移for (int j = i - 1; j >= high+1; j--) {arr[j+1] = arr[j ];}//在arr[high+1]或arr[low]处插入元素arr[high+1] = arr[0];}//for
}

1.3希尔排序

希尔排序:把相隔某个增量的元素组成一个子表,对各个子表进行直接插入排序,当整个表中基本有序的时候,再对整个表进行一次直接插入排序。

void ShellSort(int arr[], int n) {int d;//初始化d为n/2,每一轮d为上一轮的1/2for (d = n / 2; d >= 1; d /= 2) {//从每个分组的第二个元素开始,遍历剩余元素,进行直接插入排序for (int i = d+1; i <= n; i++) {if (arr[i] < arr[i - d]) {   //将arr[i]直接插入有序增量子表(组间元素对比)arr[0] = arr[i];         //暂存arr[0]int j;for (j = i - d; j > 0 && arr[j] > arr[0]; j -= d) {arr[j + d] = arr[j];   //记录后移}arr[j + d] = arr[0];       //插入}//if}//for}//for
}

2、交换排序

2.1冒泡排序

冒泡排序:从后往前两两比较相邻元素的值,若为逆序,则交换。

//交换
void swap(int& a, int& b) {int temp = a;a = b;b = temp;
}
//冒泡排序
void BubbleSort(int arr[], int n) {for (int i = 0; i < n - 1; i++) {bool flag = false;//标记此轮循环中是否发生交换//每次从数组中最后1个元素向前遍历,直到第i个元素for (int j = n - 1; j > i; j--) {//将相邻两个元素为逆序,则交换,并更改flag。if (arr[j - 1] > arr[j]) {swap(arr[j - 1], arr[j]);flag = true;}}//for//此次循环元素都是正序,则结束函数if (flag==false) return;}//for
}

2.2快速排序

快速排序
1、取当前表中的第1个元素为基准元素,找到它在表中的位置,即左边元素都小于它,右边元素都大于等于它,这样就确定了基准元素的最终位置。
2、以它为分割,递归的对两个子表进行上述操作,直到每个表都只有1个或0个元素为止。

void swap(int& a, int& b) {int temp = a;a = b;b = temp;
}
void quicksort(int arr[], int L, int R) {if (L >= R) return;    //当前区间中元素为1或0,则退出int pivot, i = L, j = R;   //i,j是两个数组下标移动//此处可做优化,将任意一个元素与arr[L]交换pivot = arr[L];while (i < j) {while (i<j && arr[j]>pivot) j--;while (i < j && arr[i] <= pivot)i++;if (i < j) //避免++--之后不满足i<j;swap(arr[i], arr[j]);}swap(arr[L], arr[i]);//此时A[L~i-1] <= A[i]<=A[i+1~R];quicksort(arr, L, i - 1); //递归左区间quicksort(arr, i + 1, R);//递归右区间
}

3、选择排序

3.1简单选择排序

简单选择排序:遍历数组,每次找到一个最小的元素插入到待排序表的表头位置。

//交换元素
void swap(int& a, int& b) {int temp = a;a = b;b = temp;
}
//简单选择排序
void SelectSort(int arr[], int n) {//遍历数组 arr[0~n-2] 最后一个元素arr[n-1]不用遍历;for (int i = 0; i < n-1; i++) {int min = i;     //标记未排序数列中最小值元素的下标,初始为第 i 个元素;for (int j = i + 1; j< n; j++) {  //从i + 1开始遍历数组if (arr[j] < arr[min])   min = j;}//for完之后min指向未排序数列中最小值元素的下标if(min!=i) swap(arr[i], arr[min]);  //交换第 i 个元素和最小值元素}
}

3.2堆排序

堆排序
1、首先建成大根堆,即堆顶元素大于左右子树的值,左右子树也满足该特性。
2、输出堆顶元素,将堆底元素送入堆顶,此时堆特性被破坏,将堆顶元素向下调整直到满足堆特性,再输出堆顶元素。
3、如此重复,直到堆中只剩一个元素为止。

//调整以k为子树的大根堆 (arr[0]中自始至终只存过arr[k])
void HeadAdjust(int arr[],int k,int len) {arr[0] = arr[k];     //arr[0]保存第k个元素for (int i = 2 * k; i <= len; i *= 2) {if (i < len&& arr[i] < arr[i + 1])  i++; //判断左右孩子谁更大,i指向更大的孩子;if(arr[0]>=arr[i])  break;  //根节点arr[0]与大孩子的值比较,大于,则筛选结束。else {  arr[k] = arr[i];  //小于,则将大孩子arr[i]调整到双亲节点上。k = i;   //调整k值,以便继续向下筛选。}}//forarr[k] = arr[0];  //被筛选节点的值放入最终位置
}void BuildMaxHeap(int arr[], int len) {//从分支节点开始从后往前,向上遍历调整;for (int i = len / 2; i > 0; i--) {HeadAdjust(arr,i,len);  //调整以i为子树的大根堆}
}//大根堆排序
void HeapSort(int arr[], int len) {BuildMaxHeap(arr, len);//从后往前遍历数组for (int i = len; i > 1; i--) {swap(arr[i], arr[1]); //交换堆顶元素和堆底元素HeadAdjust(arr,1, i-1);//调整大根堆}
}

4、归并排序

归并排序:将两个或多个有序表合并成一个有序表。

   //Merge()函数:将前后两个有序表归并成一个有序表
int *B= (int*)malloc(sizeof(int) * (maxsize+1)); //辅助数组B[]
void Merge(int A[], int L, int mid, int R) {for (int k = L; k <= R; k++)B[k] = A[k];       //将A数组元素复制到B中int i, j, k;//遍历数组for (i = L, j =mid+1, k = i; i<= mid && j<= R; k++) {if (B[i] <= B[j]) A[k] = B[i++];    //比较B中的左右子表中的元素大小,两个子表若元素相同,则优先选择左子表else A[k] =B[j++];                  //将较小值复制到A中}//将剩余元素插入到表中while (i <= mid) A[k++] = B[i++];//若一个表未检测完,复制while (j <= R) A[k++] = B[j++];  //若二个表未检测完,复制
}void MergeSort(int A[], int L, int R) {if (L < R) {int mid =(L+ R) / 2;//从中间划分两个子序列MergeSort(A, L, mid);//对左子表进行递归排序MergeSort(A, mid + 1, R); //对右子表进行递归排序Merge(A, L,mid, R); //归并}//if
}

5、基数排序

基数排序
不基于比较和移动元素来进行排序,它将一个逻辑关键字分为多个关键字,基于关键字各位的大小进行排序的。

在排序的过程中,需要使用r个队列。排序过程如下:
分配:开始时,把各个队列置为空队列,然后依次考察待排元素的关键字大小,把元素放入与关键字大小对应的队列中。
收集:把各个队列中的结点首尾相接,得到新的元素序列,从而组成新的线性表。
重复分配-收集的过程,直到有序。

王道八大排序:直接插入排序 折半插入排序 希尔排序 冒泡排序 快速排序 归并排序 基数排序相关推荐

  1. 算法研究:插入类排序(简单插入,折半插入,希尔排序)

    百度百科:有一个已经有序的数据序列,要求在这个已经排好的数据序列中插入一个数,但要求插入后此数据序列仍然有序,这个时候就要用到一种新的排序方法--插入排序法,插入排序的基本操作就是将一个数据插入到已经 ...

  2. 扑克牌式插入排序及升级版希尔排序

    插入排序 问题提出:为什么叫做扑克牌式插入排序 这里我就得给大家解释一下,为什么我要叫做扑克牌式插入排序,很简单,小编本人喜欢打扑克牌...相信扑克牌大家应该都不会陌生,打扑克牌其实不仅仅是娱乐,同时 ...

  3. 七大排序算法—图文详解(插入排序,希尔排序,选择排序,堆排序,冒泡排序,快速排序,归并排序)

    作者:渴望力量的土狗 博客主页:渴望力量的土狗的博客主页 专栏:数据结构与算法 工欲善其事必先利其器,给大家介绍一款超牛的斩获大厂offer利器--牛客网 点击免费注册和我一起刷题吧 目录 插入排序: ...

  4. python希尔排序的优缺点_Python排序搜索基本算法之希尔排序实例分析

    本文实例讲述了Python排序搜索基本算法之希尔排序.分享给大家供大家参考,具体如下: 希尔排序是插入排序的扩展,通过允许非相邻的元素进行交换来提高执行效率.希尔排序最关键的是选择步长,本程序选用Kn ...

  5. 排序上---(排序概念,常见排序算法,直接插入,希尔排序,直接选择排序,堆排序)

    排序的概念 排序:所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作. 稳定性:假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对 ...

  6. 希尔排序算法python_python算法(六)希尔排序

    python算法(六)希尔排序 希称排序 问题: 将一组乱序的数列,按从小到大(从大到小)的顺序重新排列. 方法: 设定一个初始增量, 对原始数列进行分组: 对每一个分组进行排序 设置一个更小的增量 ...

  7. [ 数据结构 -- 手撕排序算法第三篇 ] 希尔排序

    手撕排序算法系列之:希尔排序. 从本篇文章开始,我会介绍并分析常见的几种排序,大致包括插入排序,冒泡排序,希尔排序,选择排序,堆排序,快速排序,归并排序等. 大家可以点击此链接阅读其他排序算法:排序算 ...

  8. 希尔排序法。Java实现希尔排序

    前言基础: 1.因为希尔排序法的步长选取不是固定的,不同的步长会对应不同的复杂度,但是综合起来希尔排序法的时间复杂度是在O(nlogn)~O(n2)之间,近似为O(n的1.3次幂).空间复杂度为O(1 ...

  9. 【八大排序详解~C语言版】直接插入排序-希尔排序- 直接选择排序-堆排序-冒泡排序-快速排序-归并排序-计数排序

    八大排序 1.直接插入排序 2.希尔排序 3.直接选择排序 直接选择排序改进 4.堆排序 1.建堆 2.利用堆删除思想来进行排序 5.冒泡排序 6.快速排序 递归实现 非递归实现 7.归并排序 递归实 ...

最新文章

  1. 嵌套母版页中的控件访问
  2. 华为鸿蒙会选择开源吗,而华为已经承诺鸿蒙系统会彻底开源,鸿蒙是开源系统...
  3. SRAM Controller
  4. nvidia控制面板点了没反应win7_为什么没有nvidia控制面板_win7没有nvidia控制面板怎么找回-系统城...
  5. 前端学习(1863)vue之电商管理系统电商系统之绘制登录表单区域
  6. 为了养成NLP卷王,我画了一张路线图
  7. 浅析ReentrantLock重入锁
  8. ELK 6.2版本部署
  9. javaSE基础之字符串
  10. linux 远程shell,linux 远程shell 实现
  11. wpf 复制到粘贴板_将WPF UI单元复制到剪贴板-阿里云开发者社区
  12. matlab波形转换,matlab波形图怎么转换为矢量图并导出?
  13. 华为云空间兑换码在哪里找_华为云空间
  14. 【正点原子MP157连载】第二十八章 A7和M4联合调试-摘自【正点原子】STM32MP1 M4裸机CubeIDE开发指南
  15. 就业技术书文件表格_《就业规划书》模板
  16. 供需关系——需求与满意度
  17. 【装机软件】Chrome浏览器
  18. 2020年程序员互联网薪资出炉!你能猜到有多少呢?
  19. windows 密码破解法
  20. js判断浏览器环境、内核、载体、外壳、操作系统等

热门文章

  1. 台式计算机怎么强制关机,电脑怎么强制关机(关机方法都在这)
  2. (损人损己)做代码质量检查差事最易得罪人,大多是为公司干好事给自己树敌的差事...
  3. Vue父组件与子组件传递事件/调用事件
  4. unity3d 鼠标点击事件处理 处理鼠标点击
  5. Splunk中12小时制AM/PM的日期转换
  6. JAVA后端如何保证业务操作的幂等性
  7. UVa 12096 The SetStack Computer 【STL】【stack】
  8. 三坐标检测之测量基准面的选择
  9. 74HC245、74LVC245
  10. 电影“我是谁,没有绝对安全的系统“——黑客技术点评