您的位置:首页 > 理论基础 > 数据结构算法

数据结构-从计数排序到基数排序

2017-03-14 12:23 12 查看
一般基于比较的排序算法时间复杂度都较高,最低就是O(NlogN),想要更快的话就很难了,而计数排序则不然特定情况下计数排序有较高效率。

1. 计数排序

思路:

1)首先找出序列当中的最大和最小的数,然后通过这两个数确定一个范围,这样就可以直接建立一个范围这么大的哈希表。

2)把数对应哈希表的下标,统计次数。

3)通过哈希表,从小到大进行遍历,然后按哈希表顺序写入序列当中。



实现代码:

using namespace std;
template<class T=int>
void CountSort(T* arr, int size)
{
T max = arr[0];
T min = arr[0];
for (int i = 0; i < size; ++i)
{
if (arr[i] < min)
min = arr[i];
if (arr[i] > max)
max = arr[i];
}
int num = max - min + 1;
T* tmp = new T[num];
memset(tmp, 0,num*sizeof(T));
for (int i = 0; i < size; ++i)
{
tmp[arr[i] - min]++;
}
int index = 0;
for (int i = 0; i < num; i++)
{
while (tmp[i]--)
{
arr[index] = i + min;
}
}
delete[] tmp;
}
void Counttest()
{
int arr[] = { 1,12,4,7,6,8,8,3};
CountSort(arr, si``
eof(arr) / sizeof(arr[0]));
}


不过这有个很明显的缺点,就是当数组最大的数很大时,比如22222222,那我们岂不是要申请22222222这么多空间?比如一个数组是{1,2,22222222},这样就存在很严重的空间浪费了。

于是就有了计数排序的升级版—–基数排序。

2. 基数排序

利用多排序码实现对单个排序码排序的算法就成称为基数排序。

这里我们就用整形来比较:

思路:对数组中的数,先以个位大小进行排序再十位…等;



#include<iostream>
using namespace std;
template<class T=int>
int GetMax(T* arr,int size)
{
int n = 1;
int base = 10;
for (int i = 0; i < size; ++i)
{
while (arr[i]>=base)
{
n++;
base *= 10;
}
}
return n;
}
template<class T>
void RadixSort(T* arr, int size)
{
int n = GetMax(arr, size);
int count[10] = { 0 };
int pos[10] = { 0 };
int base = 1;
T* tmp = new T[size];
while (n--)
{
memset(count, 0, sizeof(T)*10);
for (int i = 0; i < size; ++i)
{
count[(arr[i]/base) % 10]++;//注意这里相当于除base再模10
}
pos[0] = 0;
for (int i = 1; i < 10; ++i)
{
pos[i] = count[i-1] + pos[i - 1];
}
for (int i = 0; i < size; ++i)
{
int ret = (arr[i]/base) %10;
tmp[pos[ret]++] = arr[i];
count[ret]--;
}
for (int i = 0; i < size; ++i)
{
arr[i] = tmp[i];
}
base *= 10;
}
delete[] tmp;
}
void Radixtest()
{
int arr[] = { 22,31,44,56,77,82,43,26 };
RadixSort(arr, sizeof(arr) / sizeof(arr[0]));
}


注意尽量不要太大基数
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息