Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm &引用;“到位”;MSD基数排序、堆栈空间和堆栈溢出';s_Algorithm_Sorting_Stack Overflow_Radix Sort_In Place - Fatal编程技术网

Algorithm &引用;“到位”;MSD基数排序、堆栈空间和堆栈溢出';s

Algorithm &引用;“到位”;MSD基数排序、堆栈空间和堆栈溢出';s,algorithm,sorting,stack-overflow,radix-sort,in-place,Algorithm,Sorting,Stack Overflow,Radix Sort,In Place,我真的很困惑: 然后使用下一个数字递归处理每个箱子,直到所有数字都用于排序 我很困惑,因为在我看来递归意味着O(n)堆栈空间,其中n是最长字符串的长度(以位数表示),对吗 在我看来,避免堆栈溢出的唯一方法是使用堆空间——但根据任何定义,算法都不再“到位” 那么,如何才能就地执行MSD基数排序呢?此算法之所以适用,是因为它交换了来自数组两端的两个值。例如: {110,010,111,000,011} 0仓放在左侧,1仓放在右侧。从MSD开始,一步一步排序如下: {|110,010,111,000

我真的很困惑:

然后使用下一个数字递归处理每个箱子,直到所有数字都用于排序

我很困惑,因为在我看来递归意味着O(n)堆栈空间,其中n是最长字符串的长度(以位数表示),对吗

在我看来,避免堆栈溢出的唯一方法是使用堆空间——但根据任何定义,算法都不再“到位”


那么,如何才能就地执行MSD基数排序呢?

此算法之所以适用,是因为它交换了来自数组两端的两个值。例如:

{110,010,111,000,011}
0仓放在左侧,1仓放在右侧。从MSD开始,一步一步排序如下:

{|110,010,111,000,010|}
{011|010,111,000|110}
{011,010|111,000|110}
{011,010,000||111,110}

在本例中,这可以在O(3n)时间内完成,简化为O(n)。唯一需要的额外内存是足够交换一个元素的空间。

我认为术语“就地MSD基数排序”有点误导,因为正如您所指出的,它不是严格定义为“就地”的就地算法。“就地”术语很可能指的是这样一个事实,与LSD基数排序不同,该算法不需要辅助数组来临时存储原始输入数组中的元素

MSD基数排序的空间使用与最大输入数中的位数成比例,这是正确的。为了简单起见,让n为输入数组的长度,U为数组中的最大数。MSD基数排序的运行时间是O(n log U),因为数字U中的位数是O(log U)。O(logu)是一个非常非常缓慢增长的函数。作为参考,宇宙中的原子数约为1080,约为2240。因此,如果要对任何物理进程生成的数字进行排序,递归深度最多为240,虽然很大,但肯定是可以管理的

如果你在对非常大的数字进行排序——比如说,有成千上万个比特的数字——那么你就有理由担心堆栈被吹坏了。然而,我认为,如果您有一个良好的MSD基数排序实现,这种情况极不可能发生。quicksort中有一个标准的优化,它看起来很像MSD radix sort,不进行两个分支递归调用,而是对两个范围中较小的范围进行一个递归调用以进行排序,然后从初始调用中回收堆栈帧以对较大范围进行排序。(这本质上是一种尾部调用消除)。现在,假设您将其应用于MSD基数排序。由于每个新创建的堆栈帧都在两个要排序的范围中较小的范围内工作,因此可以保证每个新堆栈帧中的元素数是前一个堆栈帧的一半。因此,堆栈可以达到的最大深度是O(logn),而不是O(logu)。为了让它吹出你的堆栈,你需要一个真正天文数字大的输入数组,不管堆栈大小如何


总而言之:你说得对,算法不到位。然而,由于堆栈深度在一个简单的实现中是O(logu),而在一个优化的实现中是O(logn),所以您不必担心这一点,除非您有一个简单的实现,并且确实有大量的输入。

考虑问一些与cs相关的问题。@RealzSlaw:我完全忘记了那个站点,谢谢。+1谢谢。请注意,这不仅仅是数字本身;字符串可以任意长。(提到这一点只是因为你提到了宇宙中原子的数量。)