定义
假设您有一个数组a[0..n-1] 进行排序,并且您想使用k 线程进行排序。
为简单起见,我们假设最小元素的值为 0,最大的元素值为 m。如果最小值不等于 0,那么您可以在将元素分配给线程期间缩放值。
拆分成线程
将您的数组划分为k 块,每个块最多包含floor(m/k) + 1 不同的元素值。
i-th 块由元素 a[j] 组成,这样:
(i - 1) * (floor(m/k) + 1) <= a[j] < i * (floor(m/k) + 1)
例如,如果您有一个包含 10 个元素的数组:
a[0..9] = {1, 2, 5, 0, 3, 7, 2, 3 ,4, 6} 和 k = 3,然后是 m = 7,这 3 个块是:
chunk_1: elements in range [0,3) -> [1, 2, 0, 2]
chunk_2: elements in range [3,6) -> [5, 3, 3, 4]
chunk_3: elements in range [6,9) -> [6, 7]
接下来,将每个块分配给一个单独的线程。每个线程对一个块进行排序并让整个数组排序,只需将所有线程的结果按顺序连接起来:
thread_1thread_2...thread_k
复杂性:
如你所知,计数排序的复杂度是O(n + L),其中n是要排序的元素个数,L是元素的最大值。
首先,请注意,您可以按比例缩小每个线程中的值,即该线程中的L < floor(m/k) + 1,因此每个线程中计数排序的复杂性始终取决于该线程中的元素数量。
如果假设值的分布是均匀的,那么每个线程中的预期元素数也是floor(m/k),因此每个线程的总复杂度为O(m/k)。