基数排序。为啥选择异或?

Posted

技术标签:

【中文标题】基数排序。为啥选择异或?【英文标题】:Radix Sort. Why Xor?基数排序。为什么选择异或? 【发布时间】:2012-05-08 16:29:55 【问题描述】:

我正在研究基数排序算法,但我无法理解一些原始源代码。

static void rad_sort_u(unsigned *from, unsigned *to, unsigned bit)

    if (!bit || to < from + 1) return;

    unsigned *ll = from, *rr = to - 1,tmp;
    while (1) 
        /* find left most with bit, and right most without bit, swap */
        while (ll < rr && !(*ll & bit)) ll++;
        while (ll < rr &&  (*rr & bit)) rr--;
        if (ll >= rr) break;
        swap(*ll, *rr);
    

    if (!(bit & *ll) && ll < to) ll++;
    bit >>= 1;

    rad_sort_u(from, ll, bit);
    rad_sort_u(ll, to, bit);


/* sort signed ints: flip highest bit, sort as unsigned, flip back */
static void radix_sort(int *a, const size_t len)

    size_t i;
    unsigned *x = (unsigned*) a;

    for (i = 0; i < len; i++) 
            x[i] ^= INT_MIN;

    rad_sort_u(x, x + len, INT_MIN);

    for (i = 0; i < len; i++) 
            x[i] ^= INT_MIN;

我不知道为什么它使用这条线 for (i = 0; i < len; i++) x[i] ^= INT_MIN;

我知道它的异或,但我不明白这个运算符在这种情况下的用法。

【问题讨论】:

对于它的价值,这段代码在其递归中有一个坏排序的堆栈溢出。要正确实现此算法,您必须先递归到较小的一半,然后对较大的一半进行尾递归(或只是 goto top;)。 【参考方案1】:

它正在切换 MSB(最高有效位)。

据我了解,INT_MIN 因使用的编译器和系统而异,但通常类似于十六进制的 0x80000000,其计算结果为二进制的 10000...0。

如果你用一个异或任何位,你切换它:

eg: if y = A xor B

y | A B
==+====
0   0 0
1   0 1
1   1 0
0   1 1

y | A 1
==+====
1   0 1
0   1 1

Therefore
A xor 1 = !A

因此,当执行该行时,x[i] 的最高位被切换。如果它是零,它现在是一。如果是 1,那么现在是 0。

简而言之:XOR 任意值 X 与 0,得到原始值 X。XOR 任意值 X 与 1,得到 X 的补码,!X。

 Y | X A
===+====
 X   X 0
!X   X 1

【讨论】:

以上是关于基数排序。为啥选择异或?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的基数排序 JAVA 实现比快速排序慢?

为啥基数排序不能首先按最高有效数字进行桶排序[重复]

为啥我的基数排序 python 实现比快速排序慢?

为啥我的分拣程序这么慢? (java中的基数/桶排序)

为啥基数排序的空间复杂度为 O(k + n)?

在基数排序中,我得到 munmap_chunk(): invalid pointer 和 Aborted (core dumped)。为啥?