我有一项大学任务,要求我使用Java中的 n 线程对Counting Sort算法进行编码。我们还没有得到更多的信息。我认为最好的方法是将数组分区为 n 部分,然后每个线程对一个部分进行排序。问题是我不确定如何正确地分区数组;我只看到了如何划分为2个部分的示例,而不是 n 部分。
如果有人能像我解释的那样为我提供如何分区的逻辑,或者给出一些伪代码,我将不胜感激。请不要使用源代码,这是我必须完成的任务。
我对实际排序没有问题,只是分区。
感谢。
答案 0 :(得分:4)
假设你有一个数组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_1
thread_2
...
thread_k
如您所知,计数排序的复杂性为O(n + L)
,其中n
是要排序的元素数,L
是元素的最大值。
首先,请注意,您可以通过这种方式缩小每个线程中的值L < floor(m/k) + 1
,因此每个线程中count排序的复杂性总是取决于该线程中元素的数量。
如果您假设值的分布是一致的,那么每个线程中预期的元素数量也是floor(m/k)
,因此每个线程的总复杂度为O(m/k)
。
答案 1 :(得分:0)
我想到的第一个想法是递归地对数组进行分区。这意味着如果你可以分区为2,你也可以分成4,对吧?
更先进和现代的方法是分割成比线程或进程更多的部分。然后将这些部分动态分配给线程。