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

    题目链接:https://leetcode.com/problems/coin-change/ 322. Coin Change My Submissions Question Total Accep ...

  2. 配置hadoop集群一

    花了1天时间最终把环境搭建好了.整理了一下,希望对想学习hadoop的有所帮助. 资料下载:http://pan.baidu.com/s/1kTupgkn 包括了linux虚拟机.jdk, hadoo ...

  3. to prof. Choi

    Dear Prof. Choi It is my great pleasure to receive your reply ,but terribly sorry for my late reply ...

  4. 速度上手LM4F LaunchPad 输出多路PWM波

    最近转战到TI的Cortex M4平台后,发现网上关于TI的LM4F120 Launchpad 资料太少了,而且其中大部分都是TI员工或者其合作伙伴提供的,例程太少,导致新手上手很慢. 我只是要实现几 ...

  5. JavaScript Patterns 2.4 For-in loop

    Principle Enumeration should be used to iterate over nonarray objects. It's important to use the met ...

  6. 浅谈JVM内存模型

    JAVA虚拟机在执行JAVA程序的时候,会把它管理的内存分成若干不同的数据区域,每个区域都有各自的用途.目前大致把JVM内存模型划分为五个区域:程序计数器,虚拟机栈,本地方法栈,堆和方法区. 程序计数 ...

  7. RDA 字库制作

    制作韩语字库为例: 1.韩语UNICODE 范围 TV_IDF_uni_korean.txt [01fa,] [02c6,02c7] [02c9,02ca] [02cd,02cd] [02d8,02d ...

  8. Java Swing Action 动作

    Swing包提供了一种非常实用的机制来封装命令,并将它们连接到多个事件源,这就是Action接口.一个动作是一个封装下列内容的对象: × 命令的说明(一个文本字符串和一个可选图标): × 执行命令所需 ...

  9. 38. ExtJS学习(四)EditorGrid可编辑表格

    转自:https://blog.csdn.net/qq_30739519/article/details/50865060

  10. vue单页面应用刷新网页后vuex的state数据丢失问题以及beforeunload的兼容性

    最近在用vue写h5项目,当使用window.location重定向页面或者刷新当前页面时, 发现当刷新网页后,保存在vuex实例store里的数据会丢失. 后来在网上查找大神的解决方案如下: exp ...