2012-05-08 18 views
2

私は基数ソートアルゴリズムを研究していましたが、元のソースコードの一部を理解できませんでした。そのは for (i = 0; i < len; i++) x[i] ^= INT_MIN;基数ソート。なぜXOR?

が、私はその排他的論理和を知って、この行を使用して、なぜ

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; 
} 

は私は知りませんが、私は、この文脈では、この演算子の使用を理解していません。

+1

ヒント: 'INT_MIN'はおそらく' 0x80000000'です。 – Mysticial

+2

ソースでコメントを読むと、その説明があります。あるいは、ソートの前に '2 ^(width-1)'を 'unsigned'として数値に加え、ソート後に再び減算することもできます。 –

+0

それは価値があるため、このコードはその再帰の悪いソートの*スタックオーバーフロー*を持っています。このアルゴリズムを正しく実装するには、最初に小さい方の半分に再帰し、大きな半分をテール再帰(または単に 'goto top;')しなければなりません。 –

答えて

2

MSB(最上位ビット)をトグルします。

INT_MINは、私の理解では使用するコンパイラやシステムによって異なりますが、一般に16進数で0x80000000のようなもので、バイナリで10000 ... 0のように評価されます。

あなたはそれトグル、1で任意のビットをXORした場合:

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です。それが1であったならば、今はゼロです。

XOR任意の値Xを0とすると、元の値Xを得ます。XOR任意の値Xを1とすると、X、!Xの補数が得られます。

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

'INT_MIX'? minとmaxの素晴らしい "ミックス"のように聞こえます。 :-) –

+0

私はちょうどあなたのコメントの前にそのタイプミスをキャッチしました。しかし、十分に速くはありません。私は助けではなく抱きしめるのが好きです;) – DevNull

+0

@Dogbert:あなたはただの性格を保っていると思います。 ; v) –

関連する問題