基数排序

算法导论中,计数排序,基数排序,桶排序是放在一起。此处也放在一起分析,最后给出基数排序的代码。

计数排序:

计数排序要求数据的范围在0到k之间的整数,引入了一个辅助数组C,数组C的大小为k,存储了待排数组中数组C的索引值的个数

    1、统计0-k即数组C的索引值的个数。

    2、对统计个数进行相应的累加,得出该索引能存放的最后的位置。//是一种压缩数据的办法!!

    3、反向进行扫描,并存入相应值,数组C的索引值的个数进行相应减一。

注意是反向扫描,重要在这里。代码在基数排序会体现。

基数排序:

基本思想:基数排序是将整数按位进行排序,从低位开始,对每一位使用稳定的排序算法如计数排序进行排序,

直到最高位排序完成,所有元素排序完成。需稳定的排序方法!

代码如下:

#include <iostream>
#include <vld.h>
using namespace std;
int get_pos(int num,int count);
void radix_sort(int *array,int n,int base,int max_num);

int main()
{
	int A[10] = {12,13,14,18,11,17,16,15,19,10};
	radix_sort(A,10,10,2);
	 
	for(int m = 0; m < 10;m++)//回收
	{
		cout<<A[m]<<"  ";
    }

	return 1;
}


int get_pos(int num,int count)
{
	int temp = 1 ;
	for(int i = 1;i <= count;i++)
	{
		temp *=10;
	}
	//int temp[10] = {1,10,100,1000,1000,10000,100000,1000000,10000000,100000000};//等等查表
	return num/temp%10;//取某一位数,最好的方式查表!
}

//BASE 可以设置成固定的 0- 9,最大值可以给定,或自己给10最大
void radix_sort(int *array,int n,int base,int max_num)
{
	
	int *count = new int[base];//基数即为桶子数
	int *p_array = new int[n];

	for(int i = 0; i < max_num;i++)
	{
		memset(p_array,0,sizeof(int)*n);
		memset(count,0,sizeof(int)*base);

		for(int k = 0; k < n;k++)//初始化count遍利一次
		{
		  count[get_pos(array[k],i)]++;
		  
		}
 
		for(int k = 1; k < base;k++)//初始化count遍利一次
		{
		   count[k] += count[k-1];  //右边界!
		   
		}
	
		for(int j = n-1; j >= 0;j--)//分配从末尾开始!否则出错!!!
		{	 
			p_array[count[get_pos(array[j],i)]-1] = array[j];
			count[get_pos(array[j],i)]-- ;//索引值减少
		}
		
		for(int m = 0; m < n;m++)//回收
		{
			array[m] = p_array[m];
		}
	}
	 
	delete [] count;//资源释放的正确!
	delete [] p_array; 
}

桶排序:

对于一组程度为N的待排序数据,将这些数据划分为M个区间(即放入M个桶中)。根据某种映射函数,

将这N个数据放入M个桶中。然后对每个桶中的数据进行排序,最后依次输出,得到已排序数据。

桶排序要求待排序的元素都属于一个固定的且有限的区间范围内

个里理解:此种方式跟hash表类似,增加了分区工作,然后将不同的桶子区间进行排序(稳定排序)。

    1、初始化工作

    2、hash分配

    3、每个区间排序

---------------------------------------------------------------------------------------------------------------------------------------------------------

以下为比较:

计数排序:

    1、范围严格,0-k区间(可以加上一个基数),适合小范围区间。

    2、不能处理浮点数。

    3、要求稳定排序。

        时间复杂度 O(n)

        空间复杂度  O(k)

基数排序:

    1、由于利用了计数排序,数据有限制,只能处理整数,但能处理大数据,因为此处针对数的某位排序!

    2、要求稳定排序。

        时间复杂度 O(k*n) ---(k为位数,n为个数)

        空间复杂度  O(n)  --- 书上说是 O(kr) (r为基数) kr为关键字范围。

桶排序:

    1、也有范围限制,需在某个至指定范围,还依赖空间分布是否均匀

    2、可以进行浮点排序

    3、速度快,空间占用多

时间复杂度 O(n)

空间复杂度  O(n+k)//k为桶子数,此处为理论值,根据所用代码多余O(n)

以上排序对数据均有要求,在一定程度上没有比较排序的通用性,但是时间复杂度好。

故而针对特定的数据,加以选择!

当碰到排序时间复杂度要求O(N),需的考虑以上情况,再者,考虑位图是否可以。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值