说明: 常见的排序算法都是比较排序,非比较排序包括计数排序、桶排序和基数排序,非比较排序对数据有要求,因为数据本身包含了定位特征,所有才能不通过比较来确定元素的位置。比较排序的时间复杂度通常为O(n2)或者O(nlogn),比较排序的时间复杂度下界就是O(nlogn),而非比较排序的时间复杂度可以达到O(n),但是都需要额外的空间开销。本文将介绍的是各种比较排序算法:

一. 各种排序算法的比较

二. 未优化的冒泡选择排序法

1.选择排序法

 void sortlist1(int *arr,int n)
{
for(int i = 0;i < n-1;i++)
{
for(int j = i+1;j < n;j++)
{
if(arr[i] > arr[j])
{
arr[i] ^= arr[j];
arr[j] ^= arr[i];
arr[i] ^= arr[j];
}
}
}
}

2.冒泡排序法

 void sortlist2(int *arr,int n)
{
for(int i = 0;i < n-1;i++)
{
for(int j = 0;j < n-1-i;j++)
{
if(arr[j] > arr[j+1])
{
arr[j] ^= arr[j+1];
arr[j+1] ^= arr[j];
arr[j] ^= arr[j+1];
}
}
}
}

三.优化冒泡选择两种排序方法

1.选择排序法的优化(以从小到大的排列顺序为例)

从上面的代码可知,选择排序法的思想是让第 i(i 从0开始) 个元素分别与其后面的每个元素进行比较,当比较结果为大于时,就进行交换,这样比较一轮下来,第i个元素成了此轮比较中的最小元素,再继续比较完所有轮,就实现了数组从小到大的排列。这样的排列使得选择排序法的交换次数过于多,降低了排序效率。所以,对选择排序法的优化方案就是:比而不换,记录下标!

 void sortlist(int *p,int n)
{
for(int i = 0;i<n;i++)
{
int idx = i;
for(int j = i+1;j<n;j++)
{
if(p[idx] > p[j])
idx = j;
}
if(idx != i)
{
p[idx] ^= p[i];
p[i] ^= p[idx];
p[idx] ^= p[i];
}
}
}

如上代码,每次内重循环之后,idx记录本次循环中比较的最小值或最大值(此处为最小值),若idx != i,则说明 i 并不是这次比较的最大或最小值,则进行交换,结束本次循环。

2.冒泡排序法优化(以从小到大为例)

冒泡排序法的思想是每轮用第 j(j从0开始) 个元素与第 j+1个元素进行比较,如果大于则交换;这样一轮下来,最大的元素就像冒泡一样到了最后,这样继续比较完所有轮,就实现了冒泡从小到大排序。由此可见,对于冒泡排序法,当某一轮中没有发生过元素的交换时,则表明整个元素序列已经有序了,从而不需要在比较下去。因此,冒泡排序的优化方案为:序而不排。

 void sortlist2(int *p,int n)
{
for(int i = 0;i<n;i++)
{
int flag = 0;
for(int j = 0;j<n-1-i;j++)
{ if(p[j] > p[j+1])
{
p[j] ^= p[j+1];
p[j+1] ^= p[j];
p[j] ^= p[j+1];
flag = 1;
}
}
if(flag == 0)
break;
}
}

如果在一个内循环之内,都为有序排列,即没发生过交换事件,则标志flag为0,直接退出循环。

四. 快速排序

排序思想:对一组元素,选取第一个元素为比较基数,然后其他元素与他进行比较,比它大的放右边,比它小的放左边,一轮完成,该元素左边都是比它自身小的,右边都是比它大的;然后分别对刚才基数左边和右边的元素重复上述操作,直至排序完成。

 void sortlist3(int *p,int low,int high)
{
if(low < high)
//判断元素是否大于1,至少2个元素才排序
int l = low;
int h = high;
int middle = p[low ];
//此处只能用p[low],不能用p[0],因为后面递归要用到
while(l < h)
{
while(p[h] >= middle && l<h)
h--;
p[l] = p[h];
while(p[l] <= middle && l<h)
l++;
p[h] = p[l];
}
p[h] = middle;
sortlist3(p,low,h-1);
sortlist3(p,h+1,high);
}
}

其中 p 为数组名,low为数组起始地址 0,high 为数组的元素个数减1。

五.插入排序法

 void insertsort(int arr[],int length,int beg = ,int step = ) {
for(int i = beg+step; i<length; i+=step) {
if(arr[i] < arr[i-step]) {
int temparr = arr[i];
int temp = i;
while(temp-step>=beg && temparr<arr[temp-step]) {
arr[temp] = arr[temp-step];
temp = temp - step;
}
arr[temp] = temparr;
}
}
}

六.希尔排序法

 void shellsort(int arr[],int length) {
cout<<"Shellsort the array: ";
int increment = length/+;
int flag = ;
while(increment>=) {
if(increment == )
flag = ;
for(int i = ; i<increment; i+=increment)
insertsort(arr,length,i,increment); //插入排序
if(flag == )
break;
increment = increment/+;
}
}

七. 归并排序法

 /*合并两个有序数组*/
void unionarray(int arr[],int beg,int mid,int end,int*p) {
int temp = mid+;
int begg = beg;
for(int i = ;i<end-beg+;i++) {
if(begg > mid)
p[i] = arr[temp++];
else if(temp>end)
p[i] = arr[begg++];
else {
if(arr[begg]>arr[temp])
p[i] = arr[temp++];
else
p[i] = arr[begg++];
}
}
for(int i = beg;i<=end;i++)
arr[i] = p[i-beg];
}
/*归并排序*/
void GuiBingsort(int arr[],int beg,int end,int *p) {
if(beg >= end)
return ;
int mid = (beg+end)/;
GuiBingsort(arr,beg,mid,p);
GuiBingsort(arr,mid+,end,p);
unionarray(arr,beg,mid,end,p);
}

八. 堆排序

 /*交换数组两个元素*/
void swap(int arr[],int a,int b) {
int temp = arr[a];
arr[a] = arr[b];
arr[b] = temp;
}
/*大顶堆维护*/
void heapAdjust(int arr[],int pos,int _size) {
int max = pos;
int lchild = pos*+;
int rchild = pos*+;
if(lchild<_size && arr[lchild]>arr[max])
max = lchild;
if(rchild<_size && arr[rchild]>arr[max])
max = rchild;
if(pos != max) {
swap(arr,pos,max);
heapAdjust(arr,max,_size);
}
}
/*堆排序主程序*/
void heapsort(int arr[],int _size) {
for(int i = _size/-;i>=;i--)
heapAdjust(arr,i,_size);
for(int i = _size-;i>;i--) {
swap(arr,i,);
heapAdjust(arr,,i);
}
}

(C/C++学习)9.C/C++优化排序的更多相关文章

  1. SQL反模式学习笔记16 使用随机数排序

    目标:随机排序,使用高效的SQL语句查询获取随机数据样本. 反模式:使用RAND()随机函数 SELECT * FROM Employees AS e ORDER BY RAND() Limit 1 ...

  2. 在Object-C中学习数据结构与算法之排序算法

    笔者在学习数据结构与算法时,尝试着将排序算法以动画的形式呈现出来更加方便理解记忆,本文配合Demo 在Object-C中学习数据结构与算法之排序算法阅读更佳. 目录 选择排序 冒泡排序 插入排序 快速 ...

  3. Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- Direct12优化

    原文:Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- Direct12优化 第一章:向量代数 1.向量计算的时候,使用XMV ...

  4. 【深度学习】深入理解优化器Optimizer算法(BGD、SGD、MBGD、Momentum、NAG、Adagrad、Adadelta、RMSprop、Adam)

    在机器学习.深度学习中使用的优化算法除了常见的梯度下降,还有 Adadelta,Adagrad,RMSProp 等几种优化器,都是什么呢,又该怎么选择呢? 在 Sebastian Ruder 的这篇论 ...

  5. 在线学习和在线凸优化(online learning and online convex optimization)—基础介绍1

    开启一个在线学习和在线凸优化框架专题学习: 1.首先介绍在线学习的相关概念 在线学习是在一系列连续的回合(rounds)中进行的: 在回合,学习机(learner)被给一个question:(一个向量 ...

  6. Python学习(三) 八大排序算法的实现(下)

    本文Python实现了插入排序.基数排序.希尔排序.冒泡排序.高速排序.直接选择排序.堆排序.归并排序的后面四种. 上篇:Python学习(三) 八大排序算法的实现(上) 1.高速排序 描写叙述 通过 ...

  7. 数值优化(Numerical Optimization)学习系列-无梯度优化(Derivative-Free Optimization)

    数值优化(Numerical Optimization)学习系列-无梯度优化(Derivative-Free Optimization) 2015年12月27日 18:51:19 下一步 阅读数 43 ...

  8. (私人收藏)python学习(游戏、爬虫、排序、练习题、错误总结)

    python学习(游戏.爬虫.排序.练习题.错误总结) https://pan.baidu.com/s/1dPzSoZdULHElKvb57kuKSgl7bz python100经典练习题python ...

  9. CUDA上的量化深度学习模型的自动化优化

    CUDA上的量化深度学习模型的自动化优化 深度学习已成功应用于各种任务.在诸如自动驾驶汽车推理之类的实时场景中,模型的推理速度至关重要.网络量化是加速深度学习模型的有效方法.在量化模型中,数据和模型参 ...

随机推荐

  1. swift 2.0 语法 字典

    //: Playground - noun: a place where people can play import UIKit /*: 字典 * 和OC的区别 * 1. {} 替换为 [] * 2 ...

  2. Magento 模块开发之DispatchEvent

    在这一章节中.我们来了解 Magento 中的事件分发机制 Mage::dispatchEvent() 在创建自己的模块时, Event 事件的分发将会变成十分实用且有效 以个人的经验. 事件的分发使 ...

  3. Date类型转换为Integer类型

    Date类型转换为Integer类型: Integer date = Integer.valueOf(String.valueOf(new SimpleDateFormat("yyyyMMd ...

  4. PX4/Pixhawk---高速成为开发人员(Windows)

    1 高速成为开发人员新手教程(翻译)---官方 1.1 编译环境之版本号控制系统 (1)安装MSysGIT 安装完毕后,配置GIT. 安装注意     安装过程中除了以下一步外,其它的步骤都採用默认安 ...

  5. mysql安装后改动port号password默认字符编码

    1.改动password grant all privileges on *.* to 'root'@'localhost' identified by 'new password'; 2.改动por ...

  6. AngularJS2.0 一个表单例子——总体说来还是简化了1.x 使用起来比较自然

    <!doctype html> <html> <head> <meta charset="utf-8"> <title> ...

  7. B1068 [SCOI2007]压缩 区间dp

    这个题我状态想对了,但是转移错了...dp的代码难度都不大,但是思考含量太高了..不会啊,我太菜了. 其实这个题就是一个正常的区间dp,中间多了一个特判的转移就行了. 题干: Description ...

  8. 你真的懂SDWebImage?

    SDWebImage已经到了用烂了的地步,对于一名优秀的开发者来说,会用只是最简单的一步,我们要能够研究到其底层的技术实现和设计思路原理.在网上偶然间看到了一篇文章,感觉不错,略作修改,批注,后面的内 ...

  9. phpStorm更新后配置svn无法使用

    phpStorm迎来新的更新,结果之前配置的svn竟然无法使用啦,快捷键一类也没有作用.各种查找解决方案,最后找到解决方案.点击File找到Settings,找到Plugins这个部分,这个部分是管理 ...

  10. SQLYog 快捷键

    SQLYog常用快捷键 Ctrl+M     创建一个新的连接Ctrl+N     使用当前设置新建连接Ctrl+F4    断开当前连接 对象浏览器F5         刷新对象浏览器(默认)Ctr ...