浅谈数据结构-交换排序(冒泡、快速)
2015-09-15 16:46
489 查看
交换排序:两两比较待排序的关键字,并交换不满足次序要求的那对数,直到整个表都满足次序要求为止。
冒泡和快速排序是交换排序算法,冒泡排序给人直观感觉是从前开始遍历,将小的元素,慢慢交换到数组前面。快速排序直观感觉是从数组两边开始,以某一值作为分组标准,从顶端和尾端开始慢慢交换。
从算法思想分析,冒泡算法实现比较简单,但从冒泡实现的细节区分,可以初级冒泡排序、一般化冒泡排序、升级版冒泡排序。
QuickSort
若初始文件是反序的,需要进行 N -1 趟排序。每趟排序要进行 N - i 次关键字的比较(1 ≤ i ≤ N - 1),且每次比较都必须移动记录三次来达到交换记录位置。在这种情况下,比较和移动次数均达到最大值:1+2+3+….+n-1 = n(n-1)/2,所以最坏时间复杂度为O(N2)。
因此,冒泡排序的平均时间复杂度为O(N2)。
总结起来,其实就是一句话:当数据越接近正序时,冒泡排序性能越好。
当数据有序时,以第一个关键字为基准分为两个子序列,前一个子序列为空,此时执行效率最差。
而当数据随机分布时,以第一个关键字为基准分为两个子序列,两个子序列的元素个数接近相等,此时执行效率最好。
所以,数据越随机分布时,快速排序性能越好;数据越接近有序,快速排序性能越差。
空间复杂度
快速排序在每次分割的过程中,需要 1 个空间存储基准值。而快速排序的大概需要 Nlog2N次 的分割处理,所以占用空间也是 Nlog2N 个。
冒泡和快速排序是交换排序算法,冒泡排序给人直观感觉是从前开始遍历,将小的元素,慢慢交换到数组前面。快速排序直观感觉是从数组两边开始,以某一值作为分组标准,从顶端和尾端开始慢慢交换。
一、冒泡算法
1、“加火”-冒泡思想
冒泡算法思想:两两比较相邻记录的关键字,如果反序则交换,直到没有反序的记录为止。从含义讲轻气泡不能在重气泡之下的原则,从下往上扫描数组s:凡扫描到违反本原则的轻气泡,就使其向上"飘浮"。如此反复进行,直到最后任何两个气泡都是轻者在上,重者在下为止。从算法思想分析,冒泡算法实现比较简单,但从冒泡实现的细节区分,可以初级冒泡排序、一般化冒泡排序、升级版冒泡排序。
2、初级冒泡排序
//快速排序 void SortAlgorithm::QuickSort(pSqlList pList) { printf("开始验证快速排序"); QuickSort(pList,1,pList->length-1); } //快速排序 inline void SortAlgorithm::QuickSort(pSqlList pList,int left,int right) { //快速排序原理是从不停迭代,类似二叉树,分组排序,注意跳出条件 //这里是if,如果是while就进入死循环 if(left<right) { //数组分组,将组内数组进行交换,让其小的在基数左边,大的基数右边 int baseposition = Division(pList,left,right); //继续迭代,将分好的左边小数数组,内部再进行快速排序 QuickSort(pList,left,baseposition-1); //继续迭代,将分好的右边大数数组,内部再进行快速排序 QuickSort(pList,baseposition+1,right); } printf("快速排序组外排序\n"); PrintSqlList(pList); } inline int SortAlgorithm::Division(pSqlList pList,int left,int right) { printf("快速排序组内数组展示"); //以左边数为基准 int base = pList->SqlArray[left]; while(left<right) { //判断右边的是否大于基准数,如果右边数小于,放在左边,否则继续向左,遍历,直到找到大于基数的. while(left<right&&pList->SqlArray[right] >= base) { right--; } //找到比base小的数后,将这个元素放在坐标数组中 pList->SqlArray[left] = pList->SqlArray[right]; // 从序列左端开始,向右遍历,直到找到大于base的数 while(left< right && pList->SqlArray[left] <= base) { left++; } // 从序列左端开始,向右遍历,直到找到大于base的数 pList->SqlArray[right] = pList->SqlArray[left]; } // /最后将base放到left位置。此时,left位置的左侧数值应该都比left小; // 而left位置的右侧数值应该都比left大。 pList-> SqlArray[left] = base; PrintSqlList(pList); return left; }
QuickSort
三、交换排序性能分析
1、冒泡排序复杂度排序方法 | 时间复杂度
| 空间复杂度 | 稳定性 | 复杂性 | |||
冒泡排序 |
| O(1) | 稳定 | 简单 | |||
快速排序 |
| O(Nlog2N)O(2) | 不稳定 | 较复杂 |
1、冒泡复杂度
若文件的初始状态是正序的,一趟扫描即可完成排序。比较次数为n-1,冒泡排序最好时间复杂度为O(N)。若初始文件是反序的,需要进行 N -1 趟排序。每趟排序要进行 N - i 次关键字的比较(1 ≤ i ≤ N - 1),且每次比较都必须移动记录三次来达到交换记录位置。在这种情况下,比较和移动次数均达到最大值:1+2+3+….+n-1 = n(n-1)/2,所以最坏时间复杂度为O(N2)。
因此,冒泡排序的平均时间复杂度为O(N2)。
总结起来,其实就是一句话:当数据越接近正序时,冒泡排序性能越好。
2、快速排序复杂度
时间复杂度当数据有序时,以第一个关键字为基准分为两个子序列,前一个子序列为空,此时执行效率最差。
而当数据随机分布时,以第一个关键字为基准分为两个子序列,两个子序列的元素个数接近相等,此时执行效率最好。
所以,数据越随机分布时,快速排序性能越好;数据越接近有序,快速排序性能越差。
空间复杂度
快速排序在每次分割的过程中,需要 1 个空间存储基准值。而快速排序的大概需要 Nlog2N次 的分割处理,所以占用空间也是 Nlog2N 个。
相关文章推荐
- cocos基础教程(5)数据结构介绍之cocos2d::Value
- 循环队列-顺序存储结构-数据结构
- cocos基础教程(5)数据结构介绍之cocos2d::Map<K,V>
- 数据结构与算法分析(c++版) #2 初涉线性表
- cocos基础教程(5)数据结构介绍之cocos2d::Vector
- 什么是数据结构?
- 《我眼中的R语言》 ——(1) 【数据结构】
- 数据结构之——归并排序
- python语法学习之数据结构
- 数据结构与算法分析(c++版) #1
- phyon数据结构
- 【数据结构】——哈希表
- 数据结构的排序总结
- 数据结构例程——迷宫问题(用队列)
- 数据结构例程——迷宫问题(用栈结构)
- 散列表查询(哈希表)之散列函数的构造方法
- 散列表查询(哈希表)之散列函数的构造方法
- 散列表查询(哈希表)之散列函数的构造方法
- 散列表查询(哈希表)之散列函数的构造方法
- 数据结构例程——表达式求值(用栈结构)