Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.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 基数排序的时间消耗_Algorithm - Fatal编程技术网

Algorithm 基数排序的时间消耗

Algorithm 基数排序的时间消耗,algorithm,Algorithm,艾伦的书中有句话我不太明白: 例如,我们可以对计算机上可表示的所有整数(32位)进行基数排序,如果我们在2^11的桶大小上进行三次遍历。在这台计算机上,此算法将始终是O(N) 为什么O(N)?我的解释假设您了解基数排序 32位字长的计算机具有2^32-1(4294967295)可能的字长整数(从0x00到0xFF) bucket size为2^11表示每个bucket通过一个11位宽的字段(0b000 0000 0000到0b111 1111 1111)收集整数 我们可以将这些整数的位分成3部分

艾伦的书中有句话我不太明白:

例如,我们可以对计算机上可表示的所有整数(
32位
)进行基数排序,如果我们在
2^11
的桶大小上进行三次遍历。在这台计算机上,此算法将始终是
O(N)


为什么
O(N)

我的解释假设您了解基数排序

32位字长的计算机具有
2^32-1
4294967295
)可能的字长整数(从
0x00
0xFF

bucket size为
2^11
表示每个bucket通过一个11位宽的字段(0b000 0000 0000到0b111 1111 1111)收集整数

我们可以将这些整数的位分成3部分,如下所示:

0b | 0000 0000 00 | 00 0000 0000 0 | 000 0000 0000
   | ^section 3 ^ | ^  section 2 ^ | ^ section 1 ^
0b0000 0000 00XX XXXX XXXX XXXX XXXX XXXX
0b0000 0000 01XX XXXX XXXX XXXX XXXX XXXX
0b0000 0000 10XX XXXX XXXX XXXX XXXX XXXX
 ...
0b1111 1111 10XX XXXX XXXX XXXX XXXX XXXX
0b1111 1111 11XX XXXX XXXX XXXX XXXX XXXX
  • 第1节是11个最不重要的位
  • 第2节是下一个最不重要的11位
  • 第3节是剩余的10位
  • 第一阶段 要执行此排序,第一个整数由其
    部分1
    位扣接。桶是这样的:

    0bXXXX XXXX XXXX XXXX XXX X000 0000 0000
    0bXXXX XXXX XXXX XXXX XXX X000 0000 0001
    0bXXXX XXXX XXXX XXXX XXX X000 0000 0011
     ...
    0bXXXX XXXX XXXX XXXX XXX X111 1111 1110
    0bXXXX XXXX XXXX XXXX XXX X111 1111 1111
    
    0bXXXX XXXX XX00 0000 0000 0XXX XXXX XXXX
    0bXXXX XXXX XX00 0000 0000 1XXX XXXX XXXX
    0bXXXX XXXX XX00 0000 0001 1XXX XXXX XXXX
     ...
    0bXXXX XXXX XX11 1111 1110 1XXX XXXX XXXX
    0bXXXX XXXX XX11 1111 1111 1XXX XXXX XXXX
    
    X
    s表示与此阶段无关的位。每个整数根据其
    节1
    位放入这些
    2^11
    桶中的一个。这是一个
    O(N)
    操作。完成后,
    2^11
    存储桶按从低到高的顺序迭代,元素被放入中间列表。现在,如果只查看元素的
    第1节
    位,则此列表中的元素已排序

    第二阶段 接下来,来自
    阶段1
    中间列表的整数被其
    部分2
    位扣住。桶是这样的:

    0bXXXX XXXX XXXX XXXX XXX X000 0000 0000
    0bXXXX XXXX XXXX XXXX XXX X000 0000 0001
    0bXXXX XXXX XXXX XXXX XXX X000 0000 0011
     ...
    0bXXXX XXXX XXXX XXXX XXX X111 1111 1110
    0bXXXX XXXX XXXX XXXX XXX X111 1111 1111
    
    0bXXXX XXXX XX00 0000 0000 0XXX XXXX XXXX
    0bXXXX XXXX XX00 0000 0000 1XXX XXXX XXXX
    0bXXXX XXXX XX00 0000 0001 1XXX XXXX XXXX
     ...
    0bXXXX XXXX XX11 1111 1110 1XXX XXXX XXXX
    0bXXXX XXXX XX11 1111 1111 1XXX XXXX XXXX
    
    每个整数根据其
    第2节
    位放入其中一个
    2^11
    桶中。这是另一个
    O(N)
    操作。一旦完成,
    2^11
    存储桶按从低到高的顺序迭代,元素被放入一个新的中间列表中。如果只查看
    第1节
    第2节
    位,则此列表中的元素现在已排序

    第三阶段 接下来,来自
    阶段2
    中间列表的整数被其
    部分3
    位扣住。理论上,如果计算机有一个
    33位的
    word大小,我们可以使用所有
    2^11
    存储桶,并在
    O(N)
    中对所有可能的
    33位的
    整数进行排序。但出于我们的目的,本阶段实际上只需要
    2^10
    存储桶,如下所示:

    0b | 0000 0000 00 | 00 0000 0000 0 | 000 0000 0000
       | ^section 3 ^ | ^  section 2 ^ | ^ section 1 ^
    
    0b0000 0000 00XX XXXX XXXX XXXX XXXX XXXX
    0b0000 0000 01XX XXXX XXXX XXXX XXXX XXXX
    0b0000 0000 10XX XXXX XXXX XXXX XXXX XXXX
     ...
    0b1111 1111 10XX XXXX XXXX XXXX XXXX XXXX
    0b1111 1111 11XX XXXX XXXX XXXX XXXX XXXX
    
    每个整数根据其
    第3节
    位放入其中一个
    2^11
    桶中。这是另一个
    O(N)
    操作。完成后,
    2^10
    存储桶按从低到高的顺序迭代,元素被放入一个新列表中。由于
    第1节
    第2节
    第3节
    位都已计算完毕,因此此列表是最终的排序结果

    总结 此过程花费了6个
    O(N)
    过程:

  • 通过
    第1节
  • 从桶中收集
  • 通过
    第2节
  • 从桶中收集
  • 通过
    第3节
  • 从桶中收集

  • 因此,总的来说,这个算法是
    O(N)

    那么,你认为它应该是什么呢?当我们不知道你的误解可能是什么的时候,很难解释一些事情。我正在写一个解释,但需要一秒钟。这很简单。正确实现的基数排序在每次传递中每个已排序元素花费恒定的精力。如果您有N个元素,并且您通过表示输入的大小有限(这里您是说将有3个过程,因为上限(32/11)=3)来固定过程的数量,那么总时间是O(常数*3*N)=O(N)。