C++实现排序算法 代码地址

vector<unsigned int> cVec;
int nSize = cVec.size();

1 冒泡排序

算法思路:
每两两相邻的数值都会比较大小,前面比后面大的时候就交换位置,否则就不动。

代码:


void BubbleSort() {//优化://可以设置一个标记为,表示前一轮是否移动过数字,如果没有则表示后一位均比前一位大//即数组已经有序bool flag =  true;//每次j循环完成后,表示数组的第i位是数组里最大的for (int i = nSize - 1; i > 0 && flag; --i) {flag = false;//从数组第一个值开始for (int j = 0; j < i; ++j) {//和后一个值比较,如果大于就交换位置if (cVec[j] > cVec[j + 1]) {std::swap(cVec[j], cVec[j + 1]);flag = true;}}}
}

每次i循环结束,cVec[i] 就是前i个最大的,就是每次循环结束,最大的那个值就会到最后面。所以j只到i

2 插入排序

算法思路:
假设前 i 个值有序(不包括 i),这时要排序i的时候就要将 i 和前面的值比较,找到一个位置j的值比他大的,这样就将这个位置后面的值 [j+1,i-1] 全部后移,将 i 位置的值覆盖。

void InsertSort() {for (int i = 1; i < nSize; ++i) {//这个是前i个数for (int j = 0; j < i; ++j) {if (cVec[i] < cVec[j]) {//这个是移动循环unsigned int temp = cVec[i];for (int k = i - 1; k >= j; --k) {cVec[k + 1] = cVec[k];}cVec[j] = temp;break;}}}
}

3 希尔排序

算法思路:
和插入算法类似,首先确定分组长度,即下标间隔为i的分为同一组:
当i=3时:
第1组为0,3,6,9
第2组为1,4,7,10
第3组为2,5,8
然后分别对这些分组进行插入排序,然后减少分组长度即 –i,重新确定分组,重新排序,直到i==0
第一个循环是确定分组长度,一般是数组长度的一半;
第二个循环是确定分组的起始下标,即分组的第一个下标位置
第三个循环和第四个循环和插入排序相同

void ShellSort() {//分组距离for (int i = nSize / 2; i > 0; i/=2) {//起始下标,即将[j]插入到前面去for (int j = 0; j < i ; ++j) {//k循环表示列举每个分组的值      for (int k = j+i; k < nSize; k += i) {//l循环表示在前面的值中找到位置插入,因为j是第一个值的位置,所以要大于他for (int l = k; l > j; l -= i) {//如果当前位置的值比前一个位置的小就交换位置,否则就已经是有序了if (cVec[l] < cVec[l - i]) {std::swap(cVec[l], cVec[l - i]);}else {break;}}}}}
}

4 选择排序

算法思路:
选择个最大/最小的值,然后和数组的尾/头交换位置
这里是选择最小值的。

void sort::SelectSort() {//每次j循环结束,表示找到一个最小的值了for (int i = 0; i < nSize; ++i) {//假设m为当前最小值的下标位置int m = i;//在m后面的下标中找到比下标m还要小的值for (int j = i+1; j < nSize; ++j) {if (cVec[m] > cVec[j]) {m = j;}}//发现这个m的值改变了,就交换他们的位置if (m != i) {std::swap(cVec[m], cVec[i]);}}
}

5 快速排序

算法思路:
设置两个变量be,分别保存数组的头和尾的下标;
设置两个变量bsiteesite保存刚开始时be的值;
再随便找一个值flag,这里就找数组的第一个值 flag=cVec[b]
0、如果b==e,表示数组里就只有1个数,那就没必要排序了,直接返回就好了;
1、从数组后面开始找,找到第一个比flag小的值,即cVec[e]<flag
2、交换他们的位置,这时cVec[e]后面的值都是比flag要大。
3、从数组前面开始找,找到第一个比flag大的值,即cVec[b]<flag
4、交换他们的位置,这是**cVec[b]前面的值都是比cVec[b]**小的值;
5、比较 b 是否等于 e:
如果是的话表示 cVec[b] 前面的值都比它小,后面的值都比它大,这样的话可以将数组以 cVec[b] 为界限,分成两个数组,分别是 cVec[bsite]-cVec[b-1]cVec[b+1]-cVec[esite]
如果不是的话回到第1步继续;

void quickSort(int b,int e) {if (b >= e) {return;}unsigned int flag = cVec[b];int bsite = b, esite = e;while (b < e) {while (b<e && flag <= cVec[e]) {--e;}if (flag > cVec[e]) {std::swap(cVec[b], cVec[e]);++b;}while (b < e && flag >= cVec[b]) {++b;}if (flag < cVec[b]) {std::swap(cVec[b], cVec[e]);--e;}}quickSort(e + 1, esite);quickSort(bsite, b-1);}

6 堆排序

算法思路:
堆分为大顶堆/小顶堆,表示双亲结点大于/小于子结点。
这里以大顶堆为例。
1、将数组构造成大顶堆,这样cVec[0] 就是最大的值了;
2、然后将cVec[0]cVec[nSize-1](也就是最后一个值)交换位置,这样nSize的值就减1,因为最后一个值已经是最大的;
3、交换位置后,数组就不是大顶堆了,这时又要重新构造大顶堆
4、重复2、3步,直到nSize0

现在问题是怎么构建大顶堆了:
每个结点的子结点的下标分别是:
左节点(left):site * 2 + 1
右结点(right):site * 2 + 2
这样的话,可以从数组的中间位置nSize/2开始递减,直到等于0:
从下标nSize/2开始,如果左右结点存在并且比父结点还大,就交换它们的位置,这样父结点就比子结点大了。

那剩下的是构造大顶堆后,也交换值的位置,怎么将交换后的数组恢复回大顶堆呢?
1、首先看看左结点是否在数组的长度内,即 site*2+1 < nSize,在的话就往下执行,不在的话表示该结点没有子结点,可以直接返回了。
2、比较cVec[site] 结点和 它的子结点cVec[site*2+1]cVec[site*2+2] 的大小;如果子结点存在且比它大,那就选最大的子结点就交换位置;如果子结点不存在那就直接返回
3、交换位置后就要修改site的值,保证site的子结点不会比它大,回到第1步,直到不存在子结点。

void buildHeapify(int site,int size) {int temp;int left = site * 2 + 1;int right = site * 2 + 2;temp = left;while (left < size) {//找到子结点中比较大的那个if (right < size && cVec[right] > cVec[left]) {temp = right;}//再和双亲结点比较大小,如果小于等于就结束if (cVec[site] >= cVec[temp]) {break;}//如果大于双亲结点就交换位置,并继续往下调整std::swap(cVec[temp], cVec[site]);site = temp;left = site * 2 + 1;right = site * 2 + 2;temp = left;}}void initHeapify() {int half = nSize / 2;for (int j = half; j >= 0; --j) {buildHeapify(j,nSize);}
}void HeapSort() {initHeapify();//initHeapify构造出大顶堆for (int i = 0; i < nSize; ++i) {std::swap(cVec[0], cVec[nSize - 1 - i]);//调整结点位置恢复大顶堆buildHeapify(0,nSize-1-i);}
}

7 归并排序

算法思路:
1、判断当前数组长度是否为1,不是就往下,是就结束
2、将当前数组以nSize/2为中心分成两段
3、对分成两段的数组进行排序

这样循环的话,将1个数组分成两个数组,分别对这两个数组进行排序,然后再将这两个数组有序地合回1个数组

怎么将两个数组合成一个有序数组:
1、比较两个数组的首项大小,将比较小的值保存到一个临时数组,移动首项的位置,即 ++
2、重复第1步,直到其中一个数组将所有的数字都保存到临时数组里面
3、将另一个数组剩下的值全都保存到临时数组里面

这是整个临时数组已经是有序的了,再将它存回到原始数组对应的位置就可以了

void mergeArray(int l,int r,int mid){std::vector<unsigned int> tempArray;int left = l;int right = mid+1;while (left <= mid&&right <= r) {while (left <= mid && cVec[left] <= cVec[right]) {tempArray.push_back(cVec[left++]);}while (right <= r && cVec[left] > cVec[right]) {tempArray.push_back(cVec[right++]);}}while (left <= mid) {tempArray.push_back(cVec[left++]);}while (right <= r) {tempArray.push_back(cVec[right++]);}for (int i = 0; i <tempArray.size(); i++) {cVec[l + i] = tempArray[i];}
}
void mergeSort(int l,int r) {if (l == r) {return;}int mid = (l + r) >> 1;mergeSort(l, mid);mergeSort(mid + 1, r);mergeArray(l,r,mid);}

c++ 基本排序算法学习相关推荐

  1. datatable的数据进行组内排序_排序算法学习分享(四)希尔排序

    排序,也称为排序算法,可以说是我们学习算法的过程中遇到的第一个门槛,也是实际应用中使用得较为频繁的算法,我将自己对所学的排序算法进行一个归纳总结与分享,如有错误,欢迎指正! 排序算法学习分享(一)选择 ...

  2. 冒泡和快速排序的时间复杂度_排序算法学习分享(二)交换排序---冒泡排序与快速排序...

    排序,也称为排序算法,可以说是我们学习算法的过程中遇到的第一个门槛,也是实际应用中使用得较为频繁的算法,我将自己对所学的排序算法进行一个归纳总结与分享,如有错误,欢迎指正! 排序算法学习分享(一)选择 ...

  3. 交换排序图解_排序算法学习分享(二)交换排序---冒泡排序与快速排序

    排序,也称为排序算法,可以说是我们学习算法的过程中遇到的第一个门槛,也是实际应用中使用得较为频繁的算法,我将自己对所学的排序算法进行一个归纳总结与分享,如有错误,欢迎指正! (一)排序的分类 排序算法 ...

  4. 排序算法学习整理一(冒泡)

    排序算法顾名思义,给元素排序,无论是从小到大也好还是从大到小也罢,都归属于排序,作为一个刚入坑但又在能力上有所欠缺的萌新来说排序算法是简直难以逾越的天坑,我曾经见过一个朋友冒泡排序敲了一周QAQ,勉强 ...

  5. 常见经典排序算法学习总结(插入、shell、冒泡、选择、归并、快排等)

    博主在学习过程中深感基础的重要,经典排序算法是数据结构与算法学习过程中重要的一环,这里对笔试面试最常涉及到的7种排序算法(包括插入排序.希尔排序.选择排序.冒泡排序.快速排序.堆排序.归并排序)进行了 ...

  6. 经典排序算法学习笔记二——快速排序

    快速排序 数据结构 不定 最差时间复杂度 O(n^2) 最优时间复杂度 O (n*log n) 平均时间复杂度 O (n*log n) 最差空间复杂度 根据实现的方式不同而不同 https://zh. ...

  7. 经典排序算法学习笔记七——堆排序

    堆排序 数据结构 数组 最差时间复杂度 O(n*log n) 最优时间复杂度 O(n*log n) 平均时间复杂度 O(n*log n) 最差空间复杂度 О(n) total, O(1) auxili ...

  8. java排序算法学习(一)--冒泡排序

    package com.tw.ds.sort; /** *<p>java数据结构之:冒泡排序方法 *冒泡排序算法的一般性策略:搜索整个值列,比较相邻元素,如果两者的相对次序不对,则交换它们 ...

  9. 排序算法学习——冒泡排序

    冒泡排序是比较容易理解的一种稳定排序方法,我们将记录关键字的顺序表elem[0--n-1]看作垂直排列,每个记录看作是重量为elem[i]的气泡.根据重气泡不能在轻的气泡上的原则,从上往下扫描,把重气 ...

最新文章

  1. [UWP小白日记-10]程序启动屏(ios解锁既视感)
  2. leveldb源码分析:数据插入与删除(Put与Delete)
  3. 6 种不同情况下写的代码
  4. MapReduce框架中map、reduce方法的运行机制
  5. B端运营级视频服务技术平台搭建
  6. 低代码发展专访系列之六:低代码平台能解决业务重构的问题么?
  7. python编的俄罗斯方块游戏_python编写俄罗斯方块
  8. Python爬虫从入门到放弃(二十)之 Scrapy分布式原理
  9. linux系统mysql创建表,Linux系统下手动新建数据库
  10. Mac安装虚拟机详细步骤
  11. 未转变者3.x局域网服务器,未转变者局域网怎么创建服务器
  12. zmud之潜能武学技能计算器。
  13. antv,图表和地图
  14. Dapper - 论文 中文版 大规模分布式系统的跟踪系统
  15. 用php实现加减乘除计算器,利用php怎么编写一个加减乘除计算器
  16. 计算机图形学必备的数学知识
  17. 解决“C2001:常量中有换行符“编译问题
  18. 几篇神经网络训练语言模型文章的阅读
  19. matlab和r语言做热图,案例演示 | R语言绘制热图代码
  20. python学生管理系统数据库_Django+Mysql实现--学生管理系统

热门文章

  1. relative布局html,CSS的四种布局方式static/relative/fixed/absolute
  2. 【APICloud系列|8】APICloud下载编译包安装,点击图标打不开,提示很抱歉,程序出现异常,即将退出
  3. linux基于域名的虚拟主机,Nginx虚拟主机应用——基于域名、IP、端口的虚拟主机...
  4. 导出oracle awr分析报告,配置oracle内存参数,察看表空间使用率
  5. linux 自动安装 yum,LINUX6安装YUM仓库和实现开机自动挂载
  6. jquery 给iframe里的元素添加事件
  7. 打印发现function toUpperCase() { [native code] }
  8. 问题:jquery给标签添加事件,但标签还未加载会成功吗
  9. Python之字符串转换为日期、结合时区的日期操作
  10. Event flow