说明: 常见的排序算法都是比较排序,非比较排序包括计数排序、桶排序和基数排序,非比较排序对数据有要求,因为数据本身包含了定位特征,所有才能不通过比较来确定元素的位置。比较排序的时间复杂度通常为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. C 基础 全局变量

    /** 被static修饰的局部变量 1.只有一份内存, 只会初始化一次 2.生命周期会持续到程序结束 3.static改变了局部变量的生命周期, 但是不能改变局部变量的作用域 被static修饰的全 ...

  2. BusyBox telnetd配置

    配置telnetd遇到的一些坑,记录一下 BusyBox版本1.22.1 Networking Utilities -->[*] telnetd 错误1: Escape character is ...

  3. 使用EL表达式正确情况下报错:javax.servlet.jsp cannot be resolved to a type

    这个错误可能是服务器自带的servlet库未导入的原因.右键项目属性,转到Targeted Runtimes,选择一个服务器,例如Tomcat,单击应用,可能就可以解决.

  4. P3178 [HAOI2015]树上操作 树链剖分

    这个题就是一道树链剖分的裸题,但是需要有一个魔性操作___编号数组需要开longlong!!!震惊!真的神奇. 题干: 题目描述 有一棵点数为 N 的树,以点 为根,且树点有边权.然后有 M 个操作, ...

  5. 37. ext 中sm什么意思

    转自:https://zhidao.baidu.com/question/112450217.htmlsm是SelectionModel的缩写默认为RowSelectionModel其他模式还有Che ...

  6. hihoCoder 数组重排

    找每个位置循环节的大小. 得到结果d1, d2, ....., dn. 最终结果cmd(d1, d2, ...., dn). 水题. 题目链接: http://hihocoder.com/contes ...

  7. 设计模式 |备忘录模式(memento)

    定义: 在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态.这样以后就可以将该对象恢复到原先保存的状态. 结构:(书中图,侵删) Originator:需要备份的类(写在便签上 ...

  8. linux 防火墙关闭

     systemctl status firewalld.servicesystemctl status iptables.service关闭防火墙,selinux15:54:43运维-李浩 2017/ ...

  9. ACM_迟到的祝福(四)

    迟到的祝福(四) Time Limit: 2000/1000ms (Java/Others) Problem Description: 据说前几天是雁来师姐的生日,作为一个15级的小鲜肉A,没及时给师 ...

  10. 使用UDEV SCSI规则在Oracle Linux上配置ASM

    对于使用ASM管理的磁盘来说,需要一种能够用于一致性标识磁盘设备及其正确的所属关系和权限的手段.在Linux系统中,可以使用ASMLib来执行这项任务,但是这样做的缺点是在操作系统上增加了额外的一层, ...