我正在尝试理解基数排序如何按位运行,所以我在互联网上找到了这个算法,但我无法理解它是如何工作的!
#include <algorithm>
#include <iostream>
#include <iterator>
// Radix sort comparator for 32-bit two's complement integers
class radix_test
{
const int bit; // bit position [0..31] to examine
public:
radix_test(int offset) : bit(offset) {} // constructor
bool operator()(int value) const // function call operator
{
if (bit == 31) // sign bit
return value < 0; // negative int to left partition
else
return !(value & (1 << bit)); // 0 bit to left partition
}
};
// Least significant digit radix sort
void lsd_radix_sort(int *first, int *last)
{
for (int lsb = 0; lsb < 32; ++lsb) // least-significant-bit
{
std::stable_partition(first, last, radix_test(lsb));
}
}
// Most significant digit radix sort (recursive)
void msd_radix_sort(int *first, int *last, int msb = 31)
{
if (first != last && msb >= 0)
{
int *mid = std::partition(first, last, radix_test(msb));
msb--; // decrement most-significant-bit
msd_radix_sort(first, mid, msb); // sort left partition
msd_radix_sort(mid, last, msb); // sort right partition
}
}
// test radix_sort
int main()
{
int data[] = { 170, 45, 75, -90, -802, 24, 2, 66 };
lsd_radix_sort(data, data + 8);
// msd_radix_sort(data, data + 8);
std::copy(data, data + 8, std::ostream_iterator<int>(std::cout, " "));
return 0;
}
任何人都可以解释这项工作如何排序整数! 非常感谢
答案 0 :(得分:2)
嗯,你说你明白了MSD基数排序是如何工作的,所以在这种情况下,关键部分是:
class radix_test {
bool operator()(int value) const // function call operator
{
...
return !(value & (1 << bit)); // 0 bit to left partition
}
}
radix_test
是一个函数,当给定值和位数时,测试该位是否未在给定值中设置。 1<<bit
会为该位编号生成一个位掩码,如果该位置位,则value & <bitmask>
会生成<bitmask>
,否则会生成0
。然后,如果未设置该位,则该人使用!
返回true。
void msd_radix_sort(... int msb = 31)
{
if (.... msb >= 0)
{
... std::partition(... radix_test(msb));
msb--; // decrement most-significant-bit
msd_radix_sort(..., msb); // sort left partition
msd_radix_sort(..., msb); // sort right partition
}
}
排序本身以第32位(位ID 31)开始,并使用std::partition
将所有未设置该位的值放在左侧,并将该位设置在右侧。然后用下一个较小的位对两半进行递归。当它到达结束时,数据被排序。
由于此实现适用于单比特级(因此基数为2),因此这实际上是一种快速排序。当你改变它们以使用更多的组(非就地)时,radix排序可以真正发挥作用,但它高度依赖于数据的类型和数量。有四十亿个使用全部值的整数,我可能会使用524288个桶而不是两个,然后只需切换到一个内部,而不是递归。