只是想知道是否有人能够看一下这段代码来实现quicksort算法并回答我几个问题,请: - )
public class Run
{
/***************************************************************************
* Quicksort code from Sedgewick 7.1, 7.2.
**************************************************************************/
public static void quicksort(double[] a)
{
//shuffle(a); // to guard against worst-case
quicksort(a, 0, a.length - 1, 0);
}
static void quicksort(final double[] a, final int left, final int right, final int tdepth)
{
if (right <= left)
return;
final int i = partition(a, left, right);
if ((tdepth < 4) && ((i - left) > 1000))
{
final Thread t = new Thread()
{
public void run()
{
quicksort(a, left, i - 1, tdepth + 1);
}
};
t.start();
quicksort(a, i + 1, right, tdepth + 1);
try
{
t.join();
}
catch (InterruptedException e)
{
throw new RuntimeException("Cancelled", e);
}
} else
{
quicksort(a, left, i - 1, tdepth);
quicksort(a, i + 1, right, tdepth);
}
}
// partition a[left] to a[right], assumes left < right
private static int partition(double[] a, int left, int right)
{
int i = left - 1;
int j = right;
while (true)
{
while (less(a[++i], a[right]))
// find item on left to swap
; // a[right] acts as sentinel
while (less(a[right], a[--j]))
// find item on right to swap
if (j == left)
break; // don't go out-of-bounds
if (i >= j)
break; // check if pointers cross
exch(a, i, j); // swap two elements into place
}
exch(a, i, right); // swap with partition element
return i;
}
// is x < y ?
private static boolean less(double x, double y)
{
return (x < y);
}
// exchange a[i] and a[j]
private static void exch(double[] a, int i, int j)
{
double swap = a[i];
a[i] = a[j];
a[j] = swap;
}
// shuffle the array a[]
private static void shuffle(double[] a)
{
int N = a.length;
for (int i = 0; i < N; i++)
{
int r = i + (int) (Math.random() * (N - i)); // between i and N-1
exch(a, i, r);
}
}
// test client
public static void main(String[] args)
{
int N = 5000000; // Integer.parseInt(args[0]);
// generate N random real numbers between 0 and 1
long start = System.currentTimeMillis();
double[] a = new double[N];
for (int i = 0; i < N; i++)
a[i] = Math.random();
long stop = System.currentTimeMillis();
double elapsed = (stop - start) / 1000.0;
System.out.println("Generating input: " + elapsed + " seconds");
// sort them
start = System.currentTimeMillis();
quicksort(a);
stop = System.currentTimeMillis();
elapsed = (stop - start) / 1000.0;
System.out.println("Quicksort: " + elapsed + " seconds");
}
}
我的问题是:
变量tdepth
的目的是什么?
这被认为是并行快速排序的“正确”实现吗?我问,因为它不使用implements Runnable
或extends Thread
...
如果还没有,是否可以修改此代码以使用多个线程?通过传递要用作参数的线程数,例如......?
非常感谢,
布赖恩
答案 0 :(得分:5)
1。它用于跟踪递归深度。检查这是否决定是否并行运行。注意当函数并行运行时,它如何传递tdepth + 1(在被调用的quicksort参数中变为tdepth)。这是避免太多并行线程的基本方法。
2。是的,它肯定是使用另一个线程。代码:
new Thread()
{
public void run()
{
quicksort(a, left, i - 1, tdepth + 1);
}
};
创建一个anonymous inner class(扩展Thread),然后启动它。
答案 1 :(得分:2)
显然,tdepth用于避免创建太多线程
它使用匿名类,隐式扩展Thread
它已经这样做了(见第1点。)
答案 2 :(得分:0)
tdepth
存在,因此创建的线程数有一个上限。请注意,随着方法递归调用自身(在新线程中完成),tdepth会递增1。这样,只有前四个级别的递归才会创建新线程,大概是为了防止用多线程重载操作系统,效果不大。
此代码在quicksort
方法的定义中启动自己的线程,因此它将使用并行处理。有人可能会说,它可以通过某种线程管理来实现,例如某种Executor
可能会更好,但肯定是平行的。查看对new Thread() ...
的来电,然后是start()
。顺便说一句,对t.join()
的调用将导致当前线程等待线程t
完成,以防您不知道。
此代码已使用多个线程,但您可以调整在tdepth上进行比较时产生的线程数;增加或减少该值将决定递归级别创建多少级别。您可以完成重写代码以使用执行程序和线程池,或者可能执行三次递归而不是二进制 - 但我怀疑在您要求的意义上;不,没有简单的方式来调整线程数。
答案 3 :(得分:0)
我确实用Java编写了一个(正确的)多线程QuickSort,所以也许我可以帮一下......
对于任何有兴趣的人都在这里提问:
Multithreaded quicksort or mergesort
变量的目的是什么 tdepth?
正如其他人所评论的,它用于确定是否创建新线程。
这被认为是“适当的” 实现并行 快速排序?我问,因为它没有 使用实现Runnable或extends 螺纹...
我不认为这是正确的有几个原因:首先你应该让它依赖于CPU。在仅具有一个核心的CPU上产生16个线程毫无意义:单线程QuickSort将优于单核心机器上的多线程QuickSort。在16核机器上,当然可以激活16个线程。
Runtime.getRuntime().availableProcessors()
然后我真的不喜欢它的第二个原因是它使用了上世纪的低级Java特性线程细节:我更喜欢远离 .join()并使用更高版本等级事物(参见另一个问题中的fork / join或类似CountDownLatch'es等)。像Java的线程“加入”这样的低级问题是它没有任何有用的含义:这是100%Java特定的,可以被更高级别的线程设施所取代,它们的概念可以跨语言移植。
然后不要在开头评论洗牌。永远。我已经看过数据集,如果你删除那个shuffle,QuickSort会以二次方式降级。它只是一个O(n)shuffle,不会减慢你的排序:)
如果还没有,是否可能 修改此代码以使用多个 线程?通过传递数量 你想要用作的线程 参数,例如......?
我尝试使用更高级别的并发工具编写和/或重用实现。请查看我前一段时间提出的问题中的建议。