算法复杂度

稳定:如果a原本在b前面,而a=b,排序之后a仍然在b的前面。

不稳定:如果a原本在b的前面,而a=b,排序之后 a 可能会出现在 b 的后面。

时间复杂度:对排序数据的总的操作次数。反映当n变化时,操作次数呈现什么规律。

空间复杂度:是指算法在计算机内执行时所需存储空间的度量,它也是数据规模n的函数。

一:冒泡排序

经典的排序算法,通过依次比较相邻两个元素之间的大小,从头比较到尾,相当于一个水泡从下面一直往上,故而称为冒泡排序。

步骤:1.比较两个相邻元素的大小,如果比它大(小),就将其交换。

2.从下标0开始扫描,一直扫描到尾部,每次比较都将最大(小)的交换至最后。

3.继续比较,重复上述过程。

代码:

void Bubble Sort(int *arr,int len)
{for(int i=0;i<len-1;++i) //比较的次数{for(int j=0;j<len-i-1;++j) {if(arr[j]>arr[j+1])swap(arr[j],arr[j+1]);}}
}

二:选择排序

选择排序(Selection-sort)是一种简单直观的排序算法。它的工作原理:首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。

步骤:

1.先进行第一次比较,找出数组最大(小)的元素,将其放在第一位,目前已知第一位是最大(小)的元素。

2.从第二个下标位置开始,找出剩余数组中最大(小)的元素,放在第二位。

3.继续重复寻找,直到将其全部排序

代码:

void Select Sort(int *arr,int len)
{int temp;for(int i=0;i<len-1;++i){temp=i;for(int j=i+1;j<len;++j){if(arr[j]>arr[j+1])temp=j;}swap(arr[i],arr[temp]);}
}

三:插入排序

插入排序(英语:Insertion Sort)是一种简单直观的排序算法。它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。

步骤:

1.首先认为第一个元素是已经排序好的,那么从第二个元素开始,如果比第一个小,那么就将其排在第一位,第一个元素后移。

2.同样,继续从第三个开始,从已经排序好的后面开始比较,如果比第二个小,就与第一个比较,元素依次后移。

3.对后面的元素重复操作,一直到比较完成。

代码:

void Insert Sort(int *arr,int len)
{int temp;for(int i=1;i<len;++i){int j=i-1;temp=arr[i];while(j>=0 && temp>arr[j]){arr[j+1]=arr[j];--j;}arr[j+1]=temp;}
}

四:希尔排序

      希尔排序,也称递减增量排序算法,是插入排序的一种更高效的改进版本。希尔排序是非稳定排序算法。

希尔排序是基于插入排序的以下两点性质而提出改进方法的:

插入排序在对几乎已经排好序的数据操作时,效率高,即可以达到线性排序的效率。

但插入排序一般来说是低效的,因为插入排序每次只能将数据移动一位。

先将整个待排元素序列分割成若干个子序列(由相隔某个“增量”的元素组成的)分别进行直接插入排序,然后依次缩减增量再进行排序,待整个序列中的元素基本有序(增量足够小)时,再对全体元素进行一次直接插入排序。因为直接插入排序在元素基本有序的情况下(接近最好情况),效率是很高的,因此希尔排序在时间效率上比前两种方法有较大提高。

代码:

void shellsort1(int a[], int n)
{int i, j, gap;for (gap = n / 2; gap > 0; gap /= 2) //步长for (i = 0; i < gap; i++)        //直接插入排序{for (j = i + gap; j < n; j += gap) if (a[j] < a[j - gap]){int temp = a[j];int k = j - gap;while (k >= 0 && a[k] > temp){a[k + gap] = a[k];k -= gap;}a[k + gap] = temp;}}
}

但这种略显复杂,稍做优化

void shellsort2(int a[], int n)
{int j, gap;for (gap = n / 2; gap > 0; gap /= 2)for (j = gap; j < n; j++)//从数组第gap个元素开始if (a[j] < a[j - gap])//每个元素与自己组内的数据进行直接插入排序{int temp = a[j];int k = j - gap;while (k >= 0 && a[k] > temp){a[k + gap] = a[k];k -= gap;}a[k + gap] = temp;}
}

五:归并排序

归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为2-路归并。

  • 把长度为n的输入序列分成两个长度为n/2的子序列;
  • 对这两个子序列分别采用归并排序;
  • 将两个排序好的子序列合并成一个最终的排序序列。
//将有二个有序数列a[first...mid]和a[mid...last]合并。
void mergearray(int a[], int first, int mid, int last, int temp[])
{int i = first, j = mid + 1;int m = mid,   n = last;int k = 0;while (i <= m && j <= n){if (a[i] <= a[j])temp[k++] = a[i++];elsetemp[k++] = a[j++];}while (i <= m)temp[k++] = a[i++];while (j <= n)temp[k++] = a[j++];for (i = 0; i < k; i++)a[first + i] = temp[i];
}
void mergesort(int a[], int first, int last, int temp[])
{if (first < last){int mid = (first + last) / 2;mergesort(a, first, mid, temp);    //左边有序mergesort(a, mid + 1, last, temp); //右边有序mergearray(a, first, mid, last, temp); //再将二个有序数列合并}
}bool MergeSort(int a[], int n)
{int *p = new int[n];if (p == NULL)return false;mergesort(a, 0, n - 1, p);delete[] p;return true;
}

六:快速排序

想必用的最多的就是快排了吧,用sort用得不亦乐乎。好吧,回归正话。

快速排序使用分治法(Divide and conquer)策略来把一个序列(list)分为两个子序列(sub-lists)。

步骤为:

  1. 从数列中挑出一个元素,称为“基准”(pivot),
  2. 重新排序数列,所有比基准值小的元素摆放在基准前面,所有比基准值大的元素摆在基准后面(相同的数可以到任何一边)。在这个分区结束之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。
  3. 递归地(recursively)把小于基准值元素的子数列和大于基准值元素的子数列排序。

递归到最底部时,数列的大小是零或一,也就是已经排序好了。这个算法一定会结束,因为在每次的迭代(iteration)中,它至少会把一个元素摆到它最后的位置去。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int Partion(int *arr,int low,int high)
{int temp=arr[low];while(low<high){while(low<high && arr[high]>=temp)--high;swap(arr[low],arr[high]);//arr[low]=arr[high];while(low<high && arr[low]<=temp)++low;swap(arr[low],arr[high]);//arr[high]=arr[low];}return low;
}void quicksort(int *arr,int low,int high)
{if(low<high){int t=Partion(arr,low,high);quicksort(arr,low,t-1);quicksort(arr,t+1,high);}
}int main()
{int a[5];for(int i=0;i<5;++i)scanf("%d",&a[i]);quicksort(a,0,4);printf("%d %d %d %d %d",a[0],a[1],a[2],a[3],a[4]);return 0;
}

待更新……

(PS:本期部分素材来源于https://www.cnblogs.com/onepixel/articles/7674659.html)

转载于:https://www.cnblogs.com/aerer/p/9930989.html

排序算法总结(C++)相关推荐

  1. 伍六七带你学算法 进阶篇-排序算法

    给定一个整数数组 nums,将该数组升序排列. 示例 1: 输入:[5,2,3,1] 输出:[1,2,3,5] 示例 2: 输入:[5,1,1,2,0,0] 输出:[0,0,1,1,2,5] 各排序算 ...

  2. C++排序算法实现(更新中)

    比较排序法:如冒泡排序.简单选择排序.合并排序.快速排序.其最优的时间复杂度为O(nlogn). 其他排序法:如桶排序.基数排序等.时间复杂度可以达到O(n).但试用范围有要求. 桶排序:排序的数组元 ...

  3. 十种经典排序算法精粹(c语言版本)

    下面给出这段时间我苦心研究验证过的十种经典排序算法的C语言版本,即下面的排序算法: 插入排序,shell排序,冒泡排序,快速排序,选择排序,堆排序,归并排序,桶排序,基数排序和计数排序.整理出来以作备 ...

  4. 十大排序算法 导图总结

    以下为我们经常用到的十大典型排序算法导图,很多设计以及优化的思想值得去参考学习 因为代码较多,所以都添加到对应的实现注释中了,相关代码可以从Mind-mapping获取xmind源文件 参考文档: 基 ...

  5. C++实现十大排序算法(冒泡,选择,插入,归并,快速,堆,希尔,桶,计数,基数)排序算法时间复杂度、空间复杂度、稳定性比较(面试经验总结)

    排序算法分类 内部排序算法又分为基于比较的排序算法和不基于比较的排序算法,其分类如下: 比较排序:   直接插入排序    希尔排序 (插入)  冒泡排序     快速排序  (交换) 直接选择排序  ...

  6. C++拾取——使用stl标准库实现排序算法及评测

    今天看了一篇文章,讲各种语言的优势和劣势.其中一个观点:haskell非常适合写算法,因为使用者不用去关心具体的计算机实现,而只要关注于操作语义.这让它在专心研究算法的人中非常受欢迎.所以很多时候,语 ...

  7. 常用排序算法的C++实现

    排序是将一组"无序"的记录序列调整为"有序"的记录序列. 假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在 ...

  8. python 排序算法 简书_Python---简析八大排序算法

    前言 1 .排序的概念 排序是计算机内经常进行的一种操作,其目的是将一组"无序"的记录序列调整为"有序"的记录序列. 排序分为内部排序和外部排序. 若整个排序过 ...

  9. php常见排序算去,PHP兑现常见排序算法

    PHP实现常见排序算法 //插入排序(一维数组) function insert_sort($arr){ $count = count($arr); for($i=1; $i $tmp = $arr[ ...

  10. 排序算法 - 堆排序

    堆排序是指利用堆这种数据结构所设计的一种排序算法. 类型:选择排序 时间复杂度(最坏):O(nlogn) 时间复杂度(最好):O(nlogn) 时间复杂度(平均):O(nlogn) 空间复杂度:O(1 ...

最新文章

  1. kali linux安装wine32,永恒之蓝msf下 ms17_010 (64位kali下安装wine32)
  2. android小米通知不显示电量,Android开发笔记——小米通知‘坑’ app的通知一直显示在不重要通知里 ......
  3. 中国农用喷洒机行业市场供需与战略研究报告
  4. 你不知道的javascript_为什么前端要学JavaScript?JS都有哪些逆天的功能?
  5. crontab导致磁盘空间满问题的解决
  6. android反射改theme,全局修改默认字体,通过反射也能做到
  7. CF55D Beautiful numbers
  8. 计算机组成原理----超标量流水线结构模型分析!!!
  9. 益而优有机核桃油给宝宝安全放心的油!
  10. 微信支付账号服务商快速进件H5源码
  11. dns能帮助网站快速打开吗?怎么样提升网站打开速度?
  12. crontab使用实例
  13. Contiki 系统框架
  14. php开源论坛系统,十款开源论坛系统推荐(二)
  15. Python爬虫项目分享二:《爬取周杰伦的歌曲评论》
  16. 读书笔记-偷影子的人
  17. ru0507持仓:20050428
  18. DTV 学习(四)--数字电视产业标准比较。
  19. css实现图片背景填充的正六边形
  20. uniapp小程序loading效果自带

热门文章

  1. python类的构造方法名称_Python的面向对象、Class 概念与使用
  2. 考计算机科学考研老师问,名师答疑:计算机专业考研复习6问!
  3. 手动制造报错_Windows 10驱动更新调整:不再自动安装“手动”驱动更新
  4. python子类_python创建子类的方法分析
  5. linux内存管理_架构师必读:Linux 的内存分页管理
  6. java 写文件 并发_记录一次Java文件锁引起的并发写文件问题
  7. 公众号 多服务器配置_多账号公众号分享的素材如何采集以及一键分发?
  8. 系统学习NLP(六)--语义分析
  9. python 提取邮箱的正则表达式
  10. 如何使用ant_从 0 开始,成为 Ant-Design Contributor