[C++]数据结构:排序算法Part2----快速排序、归并排序、箱子排序、基数排序

本文深入探讨了四种排序算法:快速排序、归并排序、箱子排序和基数排序。快速排序采用分而治之策略,平均时间复杂度为O(nlogn),但最坏情况下为O(n^2)。归并排序也是O(nlogn),稳定但空间复杂度较高。箱子排序是基数排序的一部分,用于将元素分配到箱子中,适用于特定场景。基数排序则通过按位排序确保稳定性,时间复杂度为O(d(n+radix))。
摘要由CSDN通过智能技术生成

接上篇博文:

[C++]数据结构:排序算法Part1----冒泡排序、选择排序、插入排序、堆排序


5.快速排序:

快速排序的核心思想是分而治之算法。所谓的分而治之,简单来说就是把复杂问题分成几个子问题,然后分别解决小问题,最后再将解组合起来,得到原问题的解。

那么分而治之如何应用到排序算法中呢?

在快速排序中,n个元素被分成了了三段。左端left,右端right,和中段middle。中段仅包含一个元素,作为基准元素,左段的各元素都小于等于中段元素,右段元素都大于等于中段元素。middle元素被称为支点。

基本的操作流程大致如下:在待排序的n个元素中任意选择一个作为基准元素(通常取第一个),把该元素放入最终的位置上,数据序列被此元素划分成两部分,所有关键字比该元素关键字小的元素放置在前一部分,所有比它大的元素放在后一部分,这个过程称为一趟快速排序。对分成的两部分重复上述过程,直到每部分只有一个元素或空为止。

快排的源码如下:

#include <iostream>  
using namespace std;  

template <class T>   
void show(T arr,int n){  
    for(int i =0;i<n-1;i++){  
        cout<<arr[i]<<",";  
    }  
    cout<<arr[n-1]<<endl;  
}  

void QuickSort( int a[], int l, int r )
{
	show(a,9);
	if (l>=r) return;
	int i, j, temp;
	temp = a[l];
	i = l; j = r;
	while (i<j) {
		while(i<j&&temp<a[j])
			j--;
		a[i] = a[j];
		while(i<j&&temp>a[i])
			i++;
		a[j] = a[i];
	}
	a[i] = temp;

	QuickSort( a, l, i-1 );
	QuickSort( a, i+1, r );
}

void main()  
{  
    int inputNumber[]={2,7,5,9,1,4,6,3,8};  
    int count = 9; 
	cout<<"原始数组:"<<endl;
	show(inputNumber,count);
	cout<<"排序过程:"<<endl;
    QuickSort(inputNumber,0,count); 
	cout<<"排序结果:"<<endl;
    show(inputNumber,count);  
}  


程序运行结果的截图:

下面来谈一下快排的复杂度问题。

快速排序的时间性能取决于快速排序递归的深度,可以用递归树来描述递归算法的执行情况。

比如{50,10,90,30, 70,40,80,60,20}在快速排序过程中的递归过程。由于我们的第一个关键字是50,正好是待排序的序列的中间值,因此递归树是平衡的,此时性能也比较好。

在最优情况下,Partition每次都划分得很均匀,如果排序n个关键字,其递归树的深度就为.log2n.+1(.x.表示不大于x的最大整数),即仅需递归log2n次,需要时间为T(n)的话,第一次Partiation应该是需要对整个数组扫描一遍,做n次比较。然后,获得的枢轴将数组一分为二,那么各自还需要T(n/2)的时间(注意是最好情况,所以平分两半)。于是不断地划分下去,我们就有了下面的不等式推断。

T(n)≤2T(n/2) +n,T(1)=0  
T(n)≤2(2T(n/4)+n/2) +n=4T(n/4)+2n  
T(n)≤4(2T(n/8)+n/4) +2n=8T(n/8)+3n  
……  
T(n)≤nT(1)+(log2n)×n= O(nlogn)

也就是说,在最优的情况下,快速排序算法的时间复杂度为O(nlogn)。

在最坏的情况下,待排序的序列为正序或者逆序,每次划分只得到一个比上一次划分少一个记录的子序列,注意另一个为空。如果递归树画出来,它就是一棵斜树。此时需要执行n‐1次递归调用,且第i次划分需要经过n‐i次关键字的比较才能找到第i个记录,也就是枢轴的位置,因此比较次数为


最终其时间复杂度为O(n2)。


平均的情况,设枢轴的关键字应该在第k的位置(1≤k≤n),数学归纳法可证明,其数量级为O(nlogn)。


再来看下快排的稳定

快速排序有两个方向,左边的i下标一直往右走,当a[i] <=a[cen

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值