算法学习(6):不基于比较的排序
不基于比较的排序
不基于比较排序的意思
前面文章中提到的排序都是数组中的数字相互比较大小进行排序,所以叫基于比较的排序,本文中所要讲的排序是不比较的排序,所以叫不基于比较的排序。
计数排序
算法思想
一个整数数组arr,里面所代表的数字大小有一个确定的范围,例如:年龄。人年龄的范围可以确定为0-200,所以准备一个长度为200的额外的数组,数组的下标就代表0-200岁的年龄,下标指向的值代表arr中该年龄出现的次数。遍历arr数组,用准备的额外的数组统计每个年龄出现的次数,最后额外数组中下标从大到小,指向的值是多少,就输出多少个下标的值。
计数排序的时间复杂度
需要遍历一遍数组arr,所以时间复杂度是0(N)
算法缺点
如果数组arr中数字的范围太大,需要准备的数组长度就太长,不适用于这种算法。
基数排序(桶排序)
算法思想
以10进制的整数数组举例,准备10个桶(要保证先进先出,所以队列最佳)分别代表数字0-9。数组从左往右遍历,先看个位数,个位数是几就进与所代表数字与其相同的桶,遍历完之后,桶从左到右依次出桶,要保证先进先出,这样就可以保留个位数字上的大小的优先级;然后看十位数字,重复上面的操作,周而复始直到最大的数字的最高位那次遍历结束(超过位数的数字此位数按0算),然后出桶,这时便排好序了。
能够排好序的原因是每次遍历都会从低位开始保留大小优先级,详细算法解释见https://www.bilibili.com/video/BV13g41157hKp=5&vd_source=77d06bb648c4cce91c6939baa0595bcd P5 01:58:40
桶排序算法的限制
要排的东西必须有进制,10进制准备10个桶,2进制准备2个桶,是几进制就准备几个桶。
桶排序的C++代码实现
int getDigit(int x, int d);
int maxbits(vector<int>& arr);
void radixSort(vector<int>& arr, int left, int right, int digit);
void RadixSort(vector<int>& arr)
{
if (arr.size() < 2)
return;
radixSort(arr, 0, arr.size() - 1, maxbits(arr));
}
int maxbits(vector<int>& arr)
{
int max = INT_MIN;
for (int i = 0; i < arr.size(); i++)
{
max = arr[i] > max ? arr[i] : max;
}
int res = 0;
while (max != 0)
{
max /= 10;
res++;
}
return res;
}
void radixSort(vector<int>& arr, int left, int right, int digit)
{
int i = 0, j = 0;
const int radix = 10;
vector<int> bucket;
bucket.resize(arr.size());
for (int d = 1; d <= digit; d++)
{
int count[radix] = {0};
for (i = left; i <= right; i++)
{
j = getDigit(arr[i], d);
count[j]++;
}
for (i = 1; i < radix; i++)
{
count[i] += count[i - 1];
}
for (i = right; i >= left; i--)
{
j = getDigit(arr[i], d);
bucket[count[j] - 1] = arr[i];
count[j]--;
}
for (i = left, j = 0; i <= right; i++, j++)
{
arr[i] = bucket[j];
}
}
}
int getDigit(int x, int d)
{
if (d == 1)
{
return x % 10;
}
int temp = x / (10 * (d - 1));
return temp % 10;
}
上述代码radixSort函数中的实现方法与思路中叙述的方法不一样,是因为radixSort函数中的方法是经过优化后的方法,优化后方法的思路见https://www.bilibili.com/video/BV13g41157hK?p=5&vd_source=77d06bb648c4cce91c6939baa0595bcd P5 02:11:50
不基于比较的排序算法的总结
考虑到不基于比较的排序的缺点,必须根据数据状况来具体决定是否采用这种算法。
浙公网安备 33010602011771号