我一直在实现基数排序(以下是目前的代码)。代码是用Java编写的,但在C/C++中同样适用。从实现中可以看出,我首先处理最高有效位,即整数的第31位。这似乎更快,因为一旦子组完成,就不再需要迭代。
例如,想象一下对单词进行排序,你只有一个以“A”开头的单词。一旦你看到A并将单词放在列表的开头,你就不必再检查单词中的其他字符。另一方面,如果你从单词的末尾开始,你必须查看每个字母,才能确定它属于列表的开头。
所以,基于这个想法,我认为MSB顺序是最快的,但我是否遗漏了什么?LSB是否由于某些原因同样快?我知道LSB执行“稳定排序”,但我没有看到任何实际好处。
请注意,在这个实现中,“基数”是二进制基数,即位。
更新
顺便说一句,在Java中,这比内置的Arrays.sort快5倍(当我进行原地排序而不是键排序时),这非常酷。
例如,想象一下对单词进行排序,你只有一个以“A”开头的单词。一旦你看到A并将单词放在列表的开头,你就不必再检查单词中的其他字符。另一方面,如果你从单词的末尾开始,你必须查看每个字母,才能确定它属于列表的开头。
所以,基于这个想法,我认为MSB顺序是最快的,但我是否遗漏了什么?LSB是否由于某些原因同样快?我知道LSB执行“稳定排序”,但我没有看到任何实际好处。
public static final int[] RadixSort_unsigned_1( int[] values1 ){ // one based key sorting
int[] keys = new int[ values1.length ];
int ctValues = values1[0];
keys[0] = ctValues;
for( int xKey = 1; xKey <= ctValues; xKey++ ) keys[xKey] = xKey;
int iFrameListSize = (int)Math.sqrt( (double)ctValues ) + 2;
int[] nextBottom = new int[ iFrameListSize ];
int[] nextTop = new int[ iFrameListSize ];
int ctFramesRemaining = 1;
int ctFramesInNextRadix = 0;
nextBottom[ 1 ] = 1; // the frame information is maintained in a circular queue
nextTop[ 1 ] = ctValues;
int xFrame = 1;
int xFrameNextRadix = 2;
int radix = 32;
while( radix > 0 ){
while( ctFramesRemaining > 0 ){ // go through all the frames and sort them
int xLow = nextBottom[ xFrame ];
int xHigh = nextTop[ xFrame ];
while( true ){ // sort frame
while( values1[ keys[ xLow ] ] == 0 ) xLow++;
while( values1[ keys[ xHigh ] ] == 1 ) xHigh--;
if( xLow > xHigh ) break;
int iLowKey = keys[xLow]; // exchange high and low
keys[xLow] = keys[xHigh];
keys[xHigh] = iLowKey;
}
if( xHigh > nextBottom[ xFrame ] ){ // add a lower frame
if( xLow < nextTop[ xFrame ] ){ // and also add an upper frame
xFrameNextRadix++;
nextBottom[ xFrameNextRadix ] = nextBottom[ xFrame ]; // bottom remains the same
nextTop[ xFrameNextRadix ] = xHigh;
xFrameNextRadix++;
nextBottom[ xFrameNextRadix ] = xLow;
nextTop[ xFrameNextRadix ] = nextTop[ xFrame ]; // top remains the same
ctFramesInNextRadix += 2;
} else { // just add the lower frame
xFrameNextRadix++;
nextBottom[ xFrameNextRadix ] = nextBottom[ xFrame ]; // bottom remains the same
nextTop[ xFrameNextRadix ] = xHigh;
ctFramesInNextRadix++;
}
} else if( xLow < nextTop[ xFrame ] ){ // just add the upper frame
xFrameNextRadix++;
nextBottom[ xFrameNextRadix ] = xLow;
nextTop[ xFrameNextRadix ] = nextTop[ xFrame ]; // top remains the same
ctFramesInNextRadix++;
} // otherwise add no new frames
ctFramesRemaining--;
}
if( ctFramesInNextRadix == 0 ) break; // done
radix--;
}
return keys;
}
请注意,在这个实现中,“基数”是二进制基数,即位。
更新
顺便说一句,在Java中,这比内置的Arrays.sort快5倍(当我进行原地排序而不是键排序时),这非常酷。