数据结构----各种排序方法总结

提示:数据结构中的排序方法包括插入排序

文章目录

    • 数据结构----各种排序方法总结
  • 一、插入排序
    • 1.直接插入排序
    • 2.折半插入排序
    • 3.希尔插入排序
  • 二、交换排序
    • 1.冒泡排序
    • 2.快速排序
  • 三、选择排序
    • 1.简单选择排序
    • 2.堆排序
  • 四、归并排序
  • 五、基数排序
  • 总结

一、插入排序

插入排序的定义:在有序序列中插入一个元素,保持序列有序,有序长度不断增加

1.直接插入排序

利用图形理清思路

void InsertSort(int a[], int n) {//在直接插入排序中,使用0号位置作为哨兵,用于暂时存放当前要插入的元素int i, j;for (i = 2; i <= n; i++) {//当前要插入的元素比前一个元素小时才要进行比较if (a[i] < a[i - 1]) {  a[0] = a[i];for (j = i - 1;a[0]<a[j]; j--) {a[j + 1] = a[j];  //数组的长度增加,元素后移}a[j + 1] = a[0];  //插入到正确的位置}}}

2.折半插入排序

折半插入排序的思想与直接插入排序的思想是差不多的,只是在查找当前要插入的元素的位置时采用了二分查找的方法,其他部分与直接插入查找一样。

void BinInsertSort(int a[], int n) {int low, high,mid;int i, j;//int temp;for (i = 2; i <= n; i++) {a[0]=a[i];low = 1;high = i - 1;//使用二分查找的方法查找当前元素应该在有序序列中的哪一个位置while (low <= high) {mid = (low + high) / 2;if (a[mid] < a[0]) {low = mid + 1;}else {high = mid - 1;}}for (j = i-1; j > low; j--) {a[j + 1] = a[j];}a[low] = a[0];}for (int i = 1; i <= n; i++) {cout << a[i] << " ";}
}

3.希尔插入排序

希尔插入排序与直接插入排序的方法是一样的,不过希尔插入排序的间隔是变化的,不恒为1,下图可以帮助我们理解希尔插入排序工作的原理:

void ShellSort(int a[], int n, int dk) {int i, j;//代码的思路都和直接插入排序类似,只不过间隔不恒为1for (i = dk + 1; i <= n; i++) {a[0] = a[i];if (a[i] < a[i - dk]) {for (j = i - dk; a[0] < a[j]; j = j - dk) {a[j + dk] = a[j];}a[j + dk] = a[0];}}
}//希尔排序
void ShellInsertSort(int a[], int n, int dlk[], int t) {//dlk[]数组表示增量序列,增量序列是不唯一的for (int i = 0; i < t; i++) {ShellSort(a,n, dlk[i]);}
}/*
用希尔插入排序的效率是与增量序列的取值有关的,希尔排序也是一种不稳定的排序方法。目前还没有办法获取一个最佳的增量序列,但是可以确定的是增量序列的最后一个元素必须为1,并且所有元素除了1无其他公因子
*/

二、交换排序

1.冒泡排序

//冒泡排序
void bubble_sort(int a[], int n) {int i, j;int temp;for (i = 1; i <= n-1; i++) {for (j = 0;j<= n - i-1; j++) {if (a[j] > a[j + 1]) {temp = a[j];a[j] = a[j + 1];a[j + 1] = temp;}}}for (int i = 0; i < n; i++) {cout << a[i] << " ";}
}

改进后的冒泡排序

//改进的冒泡排序
void BubbleSort(int a[], int n) {int i, j;int temp;int flag = 1;  //作为是否有交换的标志for (i = 1; i <= n - 1 && flag==1; i++) {flag = 0;for (j = 0; j <= n - i - 1; j++) {if (a[j] > a[j + 1]) {temp = a[j];a[j] = a[j + 1];a[j + 1] = temp;flag = 1;   //若发生交换,那么下一趟就要比较;若本趟没有发生交换,则说明数组已经排好了}}}for (i = 0; i < n; i++) {cout << a[i] << " ";}
}

2.快速排序

快速排序不适合有序或者基本有序的序列,序列越乱,那么排序的效率越高。

//快速排序
int Partition(int a[], int n, int low, int high) {a[0] = a[low];while (low < high) {while (low<high && a[high]>=a[0]) {high--;}a[low] = a[high];while (low < high && a[low] <= a[0]) {low++;}a[high] = a[low];}a[low] = a[0];return low;
}void  QuickSort(int a[], int n, int low, int high) {if (low >= high) {return;}int mid = Partition(a, n, low, high);QuickSort(a, n, low, mid - 1);QuickSort(a, n, mid + 1, high);}

三、选择排序

1.简单选择排序

图解!

void SelectSort(int a[], int n) {int k;int x;for (int i = 0; i < n-1; i++) {k = i;for (int j = i+1; j < n; j++) {if (a[j] < a[k]) {k = j;}}//如果k==i的话就不需要进行交换了if (k != i) {x = a[i];a[i] = a[k];a[k] = x;}}for (int i = 0; i < n; i++) {cout << a[i] << " ";}
}

2.堆排序

堆排序的解题思路:若输出堆顶的最小值(最大值)后,是的剩余的n-1个元素的序列重新建成一个堆,则得到n个元素的次小值(次大值)........如此反复,便能得到一个有序序列,这个过程称之为堆排序。但是,实现堆排序需要解决两个问题,分别是:
1.如何有一个无序序列建成一个堆?
2.如何在输出堆顶元素后,调整剩余元素为一个新的堆?
下面将逐一解决这两个问题,首先先解决第二个问题,因为第二个问题就相当于第一个问题的子问题
/*
* 如何在输出堆顶元素后,调整剩余元素为一个新的堆?
* 1.输出堆顶之后,以堆中最后一个元素替代
* 2.然后将根结点的值与左右子树的根结点值进行比较,并与其中的大者进行交换;
* 3.重复上述操作,直至叶子结点,将得到新的堆,称这个从堆顶至叶子的调整过程为“筛选”
*///将R[s]调整为大根堆
void HeapAdjust(int R[], int s, int m) {int rc = R[s];//下标从1开始,如果下标从0开始的话,那么j要从2*s+1开始for (int j = 2 * s; j <= m; j *= 2) {if (R[j] < R[j + 1]) {   //选择左子树与右子树中较小的一个,然后沿着一条路径向下寻找j++;}if (R[j] < rc) {     //如果找到比根结点的值要小的,则停止查找break;}R[s] = R[j];   //否则需要一直查找s = j;}R[s] = rc;   //找到位置后,将此位置的值赋值为根节点的值
}
//如何由一个无序序列建成一个堆?
//下面的例子是建立一个大根堆
void Heap(int R[],int n) {//只调整不是叶子结点的结点for (int i = n / 2; i >= 1; i--) {HeapAdjust(R, i, n);}
}
//堆排序
void HeapSort(int R[], int n) {//下标从1开始int i;int  temp;//先建立一个最大堆for (i = n / 2; i >= 1; i--) {HeapAdjust(R, i, n);}//每次都使用最后一个结点替代输出堆顶元素后的根结点for (i = n; i > 1; i--) {temp = R[i];R[i] = R[1];R[1] = temp;//替代后需要重新调整堆HeapAdjust(R, 1, i - 1);}
}

四、归并排序

图解:

//归并排序
void Merge(int  *a, int start, int mid, int end) {int i, j,k=0;int* c = new int[end-start+1];//a = new int[end - start + 1];i = start;j = mid + 1;while (i <= mid && j <= end) {if (a[i] < a[j]) {c[k++] = a[i++];}else {c[k++] = a[j++];}}while (i <= mid) {c[k++] = a[i++];}while (j <= end) {c[k++] = a[j++];}for (int s = 0; s < k; s++) {a[start + s] = c[s];}delete[] c;
}
void MergeSort(int a[],int n,int start, int end) {if (start >= end) {return;}int mid = (start + end) / 2;//下面两个递归是为了将数组进行划分,然后从下往上进行排序MergeSort(a, n, start, mid);MergeSort(a, n, mid + 1, end);Merge(a, start, mid, end);}

五、基数排序

图解



总结

提示:各种排序方法比较

数据结构----各种排序方法总结相关推荐

  1. 【数据结构】排序相关题目及各种排序方法的总结

    [数据结构之排序] 常用的排序方法有:直接插入排序.希尔排序.冒泡排序.快速排序.简单选择排序.树形选择排序.堆排序.归并排序.基数排序 提示:如有不理解的知识点,请看B站最好的数据结构老师王卓老师的 ...

  2. 数据结构 排序【简单排序(冒泡、插入)、希尔排序、堆排序、排序方法的综合比较、2套 排序汇总代码】

    目   录 第9章 排序(上) 9.1 简单排序(冒泡.插入) 1.前提 2.简单排序(冒泡排序) 3.简单排序(插入排序) 4.时间复杂度下界 9.2 希尔排序 9.3 堆排序 排序方法综合比较 排 ...

  3. 数据结构:排序趟数 / 比较次数与序列的原始状态有关的排序方法有哪些?

    先说结论 比较次数 与序列初态 无关 的算法是:二路归并排序.简单选择排序.基数排序 比较次数 与序列初态 有关 的算法是:快速排序.直接插入排序.冒泡排序.堆排序.希尔排序 排序趟数 与序列初态 无 ...

  4. 数据结构(二叉树相关、满、完全二叉树、霍夫曼树、排序方法及时间复杂度总结、)笔记-day11

    目录 前言 一.树(Tree) 1.1树及特征 1.2二叉树概念及性质 1.3二叉树存储结构及遍历 1.4链式存储编码 二.霍夫曼树(最优二叉树) 2.1权值及带权路径长度 2.2霍夫曼树特征及构建 ...

  5. 数据结构六种常见的排序方法(超详细图解内附代码)

    这里写目录标题 实验目的 实验内容 实验要求 六种排序方法细解 直接插入排序 冒泡排序 简单选择排序 希尔排序 快速排序 归并排序 六种排序好坏分析 代码段 运行结果 实验目的 1.能够清楚表述主要内 ...

  6. 数据结构排序算法(一):排序方法分类和各种排序方法的实现

    一. 实验目的 1. 掌握各种常用排序的算法思想: 2. 掌握各种常用排序的算法实现: 3. 掌握各种常用排序时间复杂度,比较各种排序的优缺点. 二.排序算法的归类: 总的排序算法分为以下几类: 1. ...

  7. CUDA(六). 从并行排序方法理解并行化思维——冒泡、归并、双调排序的GPU实现

    在第五讲中我们学习了GPU三个重要的基础并行算法: Reduce, Scan 和 Histogram,分析了 其作用与串并行实现方法. 在第六讲中,本文以冒泡排序 Bubble Sort.归并排序 M ...

  8. #转载:十大排序方法,动图展示

    一像素 </div><div id="navigator"> 博客园 首页 新随笔 联系 订阅 管理 <div class="blogSta ...

  9. 【数据结构】排序算法及优化整理

    排序算法 排序算法 选择排序 Selection Sort 插入排序 Insertion Sort 归并算法 Merge Sort 快速排序 Quick Sort 堆排序 Heap Sort 二叉堆的 ...

最新文章

  1. 用python解“BCD解密”问题
  2. 从红旗5.0提及——看Linux的内存办理
  3. react-native 安卓支持 gif动态图
  4. Asp.net中使用WEB编辑控件FCKEditor
  5. linux内存管理总结
  6. UI设计干货模板素材|数据可视化UX套件
  7. POJ 2115 模线性方程 ax=b(mod n)
  8. 北京地铁规划大全(图),买房子可以参考一下
  9. mysql navicat for mysql常用快捷键
  10. 【优化预测】基于matlab遗传算法优化BP神经网络预测【含Matlab源码 1376期】
  11. setuna截图怎么放大缩小_一款强大的电脑截图神器,快速提高工作效率,功能强大!...
  12. 全国大学生数学建模2016年A题系泊系统的设计论文与代码
  13. 印象笔记保存html,印象笔记怎么保存网页 印象笔记保存网页教程
  14. 格林威治时间转北京时间
  15. 如何在为知笔记(Wiz)和印象笔记(Evernote)之间相互迁移笔记?
  16. 快捷餐饮之店家后台OSS文件管理实现
  17. 从新手到高手c++全方位学习 pdf + 视频教程 共18章
  18. vue3.0移动端 ui_vue.js的移动UI元素
  19. Ubuntu 20.04.5安装无线网卡RTL8821CE驱动
  20. 全国计算机等级考试一级ps操作,计算机等级考试一级Photoshop操作如何制作彩塑字...

热门文章

  1. The development history and future trend of optical fiber communication technology
  2. datawhale天池大赛——task01
  3. JAVA数组首位末位互换_数组元素前移,第一个元素放置数组末位
  4. 九龙证券|次新股叠加智慧交通+信创+数字经济概念,开盘冲涨停!
  5. c语言编程 菲薄拉,C语言设计模式-封装-继承-多态
  6. React报错:The tag demo is unrecognized in this browser.If you meant to render a React component, sta
  7. Google工作10年的职场感悟
  8. 利用random随机生成汉字名字
  9. 服务器和应用系统迁移方案
  10. Influxdb自定义数据采样(CQ)