c++ 基本排序算法学习

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);}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/376297.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ios 程序学习

马上着手开发iOS应用程序&#xff1a;五、提交应用与寻找信息 2013-01-11 15:36 佚名 apple.com 我要评论(0) 字号&#xff1a;T | T本文介绍了您已经学习完如何开发一个优秀的iOS应用之后&#xff0c;应该掌握的内容&#xff0c;包括将您的应用提交到App Store让其他人下载&am…

解决SimpleButton被移除后保持OVER状态

假设场景中有一SimpleButton叫testBtn,执行下面操作&#xff1a;1.鼠标移上testBtn&#xff0c; testBtn状态变为OVER2.移除testBtn&#xff0c;removeChild(testBtn)3.5秒后重新添加testBtn到场景此时&#xff0c;看见testBtn还是OVER状态。解决方法&#xff1a;1.记录testBtn…

c++ socket学习(1.1)

本文学习相关资料&#xff1a; C/C socket编程教程 环境&#xff1a;vs2015 源码&#xff1a;本文代码 windows 如何创建客户端与服务端通信&#xff1f; TCP&#xff1a; 服务端 在windows先告诉程序我们要使用哪个版本的winsock&#xff0c;成功调用了它才能继续下去 #…

c++ socket学习(1.2)

本文学习相关资料&#xff1a; C/C socket编程教程 环境&#xff1a;vs2015 源码&#xff1a;本文代码 windows 如何创建客户端与服务端通信&#xff1f; UDP&#xff1a; 这次就没什么客户端服务端好说了&#xff0c;UDP是没有无连接的 所以改叫接收端和发送端吧 接收端 …

js高级功能与高级需求、高级期待

http://www.cnblogs.com/leadzen/archive/2008/02/25/1073404.html 简单练习题&#xff1a;http://tieba.baidu.com/p/2189347922 ---------------------- scope链 闭包 Javascript属性prototype node.js metaprogramming AMD、CMD机制 http://www.makumo.com/js-modules-amd-c…

synchronized同步锁

在多线程的情况下&#xff0c;由于同一进程的多个线程共享同一片存储空间&#xff0c;在带来方便的同时&#xff0c;也带来了访问冲突这个严重的问题。Java语言提供了专门机制以解决这种冲突&#xff0c;有效避免了同一个数据对象被多个线程同时访问。由于我们可以通过 private…

c++ socket学习(1.3)

本文学习相关资料&#xff1a; C/C socket编程教程 环境&#xff1a;vs2015 源码&#xff1a;本文代码 在这里c socket学习&#xff08;1.1&#xff09;学到了怎么样建立TCP&#xff0c;然后通过TCP连接发送、接收信息。 但是都是一次性的&#xff0c;当时是接收信息后就结束…

一个一线城市的IT白领的生活成本:3万/年

自从大学毕业&#xff0c;经济独立&#xff0c;就开始全面统计各种生活开支。仔细的去统计下&#xff0c;发现开销还是挺大的。 定理&#xff1a;开销越大&#xff0c;就意味着你每个月的收入必须越高。 三族鼎立节余族: 收入-开支 > 0月光族&#xff1a;收入-开支 0透支族…

android 编译共享ccache的缓存

1. android自带的ccache版本号(2.4版本号)过低&#xff0c;是无法支持以上的功能的&#xff0c;须要使用新版ccache。2. 最新的ccache请到http://ccache.samba.org/download.html下载3. 下载解压之后&#xff0c;在linux底下进入ccache文件夹&#xff0c;执行:./configure./mak…

一位软件工程师的6年总结

作者&#xff1a;成晓旭 “又是一年毕业时”&#xff0c;看到一批批学子离开人生的象牙塔&#xff0c;走上各自的工作岗位&#xff1b;想想自己也曾经意气风发、踌躇满志&#xff0c;不觉感叹万千……本文是自己工作6年的经 历沉淀或者经验提炼&#xff0c;希望对所有的软件工…

c++ socket学习(1.4)

本文学习相关资料&#xff1a; C/C socket编程教程 环境&#xff1a;vs2015 源码&#xff1a;本文代码 前面学到了TCP怎么循环发包&#xff0c;但是TCP连接的话会出现一个问题粘包。 TCP连接接收到的数据并不是马上读取到内存里面的&#xff0c;而是放在缓冲区&#xff0c;让…

mongodb中分页显示数据集的学习

mongodb中分页显示数据集的学习 这次继续看mongodb中的分页。首先依然是插入数据&#xff1a; 1&#xff09; db.Blog.insert( { name : "Denis", age : 20, city : "Princeton" } ) db.Blog.insert( { name : "Abe", age : 30, city : &quo…

学习编程,英语很重要!!

学会编程&#xff0c;可能不需要英语多好&#xff0c;但是学号编程&#xff0c;英语真的很重要&#xff01;&#xff01;&#xff01; 好多文档&#xff0c;demo全是英文的&#xff0c;蛋疼&#xff0c;应许需要学习&#xff01;&#xff01;&#xff01;转载于:https://www.cn…

c++ socket学习(1.5)

本文学习相关资料&#xff1a; C/C socket编程教程 环境&#xff1a;vs2015 源码&#xff1a;本文代码 这次来试一下使用TCP来传输文件&#xff0c;其实传输数据和差不多&#xff0c;就是多一个读取文件&#xff0c;和一个写文件而已。 服务端 int readlan 100; std::ifst…

matlab生成HEX文件-任意信号 大于64K长度

HEX文件格式不赘述&#xff0c;写里直接放上代码。请批评改正。 1 %%convert a signal data into hex file format2 % data format:16bit 3 % signal length: less than 2^24-14 % author: Yang Li yangli0534gmail.com5 % data:2015.01.276 7 clear all;8 close all;9 clc; 10…

移动端网页中ViewPort的使用

<meta name"viewport" content"widthdevice-width,target-densitydpihigh-dpi, initial-scale1.0, minimum-scale1.0, maximum-scale1.0, user-scalableno"> <meta name”viewport” content”widthdevice-width, initial-scale1.0, user-scalabl…

c++ socket学习(1.6)

本文学习相关资料&#xff1a; C/C socket编程教程 环境&#xff1a;vs2015 源码&#xff1a;本文代码 这次来看看UDP 之前在c socket学习&#xff08;1.2&#xff09;讲过UDP怎么发送了&#xff0c;那现在来做一个可以一直发送的。 这次没有什么接收端和发送端了&#xff0…

redis学习笔记——(1)

1. NoSQL&Redis介绍 NoSQL&#xff0c;Not Only SQL&#xff0c;是非关系型的数据库。传统的关系数据库不能满足超大规模和高并发的应用。 是以Key-Value的形式存储&#xff0c;&#xff08;例如JSON,XML&#xff09;&#xff0c;不一定遵循传统数据库的一些基本要求&#…

命令模式坚决svn树冲突(local unversioned, incoming add upon update)

当工作目录修改删除过时更新使用svn更新就容易发生树冲突“Tree Confilict”.会出现类似提示。 local unversioned, incoming add upon update1local unversioned,incoming add upon update如果使用图形化客户端可以通过对比文件和解决冲突按钮进行解决&#xff0c; 如果是使用…

c++ vector学习

参考资料&#xff1a; cppreference.com 本文代码&#xff1a; 本文源码 目录隐式成员函数1.operator &#xff08;赋值给容器&#xff09;2.assign &#xff08;将值赋给容器&#xff09;元素访问3.at &#xff08;访问指定元素&#xff0c;进行下标检查&#xff09;4.operat…