java - 如何在 Java 上实现多线程就地合并排序
问题描述
什么是在 Java 中实现 Mergesort 算法以使其满足以下条件的有效方法:
- 必须是多线程的。
- 必须保留 Mergesort 时间复杂度。
- 必须就地实现,不能复制数组。
- 必须使用 Java Collection 类,而不是数组。
- 必须在任何 Java Comparable 上工作。
我的解决方案涉及使用 ArrayList 和 fork-join 来创建就地合并排序。我已经在多个输入上对此进行了测试,它们都可以工作。
我很好奇是否有人能找到一种方法来改进我的代码。要么是更有效的解决方案,要么是我没有解决的边缘案例。
import java.util.*;
import java.util.concurrent.*;
public class MergeSort<N extends Comparable<N>> extends RecursiveTask<List<N>> {
private List<N> elements;
public MergeSort(List<N> elements) {
this.elements = elements;
}
@Override
protected List<N> compute() {
if(this.elements.size() <= 1)
return this.elements;
else {
final int pivot = this.elements.size() / 2;
MergeSort<N> leftTask = new MergeSort<N>(this.elements.subList(0, pivot));
MergeSort<N> rightTask = new MergeSort<N>(this.elements.subList(pivot, this.elements.size()));
leftTask.fork();
rightTask.fork();
List<N> left = leftTask.join();
List<N> right = rightTask.join();
merge(left, right);
return this.elements;
}
}
private void merge(List<N> left, List<N> right) {
int leftIndex = 0;
int rightIndex = 0;
while(leftIndex < left.size()) {
if(rightIndex == 0) {
if( left.get(leftIndex).compareTo(right.get(rightIndex)) > 0 ) {
swap(left, leftIndex++, right, rightIndex++);
} else {
leftIndex++;
}
} else {
if( right.get(0).compareTo(right.get(rightIndex)) < 0 ) {
swap(left, leftIndex++, right, 0);
} else {
swap(left, leftIndex++, right, rightIndex++);
}
}
}
if(rightIndex < right.size() && rightIndex != 0)
merge(right.subList(0, rightIndex), right.subList(rightIndex, right.size()));
}
private void swap(List<N> left, int leftIndex, List<N> right, int rightIndex) {
left.set(leftIndex, right.set(rightIndex, left.get(leftIndex)));
}
public static void main(String[] args) {
ForkJoinPool forkJoinPool = ForkJoinPool.commonPool();
List<Integer> result = forkJoinPool.invoke(new MergeSort<Integer>(new ArrayList<>(Arrays.asList(1,3,5,7,2,4,6))));
System.out.println("result: " + result);
}
}
解决方案
推荐阅读
- hybris - cmssite 和前端扩展之间的链接
- postgresql - 无法将数据从 csv 文件导入 postgres
- java - Android中涉及measureLimit的神秘indexOutOfBoundsException
- c# - 如何检查单选按钮是否在 MVC 视图中被选中?
- azure - 如何在生产中的 Nuxt 静态文件响应中添加 CORS 标头?
- node.js - 防止 React 网站的 Express/mssql API 易受 SQL 注入攻击的最有效方法是什么?
- python - 为什么 H2(同源组 2)出现在 RIPSER 的二维(二维)图中?
- salt-stack - global.sls (SALT) 中的转义字符
- excel - Excel“填写”时间突然急剧增加(大型电子表格)
- c# - ASP.Net MVC Web 应用程序渲染视图与连续 Ping 异步