我有问题。我需要使用java实现multipath两阶段自然平衡合并。我在这里看到了合并排序示例http://www.vogella.de/articles/JavaAlgorithmsMergesort/article.html 我理解它是如何工作的,但我不知道如何实现两阶段合并。一个函数为索引划分数组,第二个是排列合并。它也应该为数组和文件(而不是数组使用的文件)实现。谁知道怎么做?
答案 0 :(得分:1)
public class Mergerer {
private int countWay = 0;
private int countIndex = 0;
private Double[] base;
private Double[] sortBase;
private Double[] tempBase;
private Double[][] arrayWay;
private String[] array1;
private String[] array2;
private String[] array3;
private String[] array4;
private String[] array5;
private String[] array6;
List<String[]> listA = new ArrayList<String[]>();
private int countElements = 0;
public Double[] getSortBase() {
return sortBase;
}
public Double[] sort() {
divide();
merger(base);
return sortBase;
}
public int getCountWay() {
return countWay;
}
public Mergerer(Double[] base, int countWay) {
this.countWay = countWay;
this.arrayWay = new Double[countWay][base.length + 1];
tempBase = base;
countElements = base.length;
array1 = new String[base.length * 2];
array2 = new String[base.length * 2];
array3 = new String[base.length * 2];
array4 = new String[base.length * 2];
array5 = new String[base.length * 2];
array6 = new String[base.length * 2];
listA.add(array1);
listA.add(array2);
listA.add(array3);
listA.add(array4);
listA.add(array5);
listA.add(array6);
}
public int divide() {
int[][] posWay = new int[countWay][1];
int beginIndexPos = 0;
int numberWay = 0;
int pos = 0;
for (int i = 1; i < tempBase.length; i++) {
if (tempBase[i] < tempBase[i - 1]) {
for (int j = beginIndexPos; j < i; j++) {
listA.get(numberWay)[posWay[numberWay][0]] = Double.toString(tempBase[j]);
arrayWay[numberWay][posWay[numberWay][0]] = tempBase[j];
posWay[numberWay][0]++;
countIndex++;
}
listA.get(numberWay)[posWay[numberWay][0]] = "'";
posWay[numberWay][0]++;
beginIndexPos = i;
if (numberWay == countWay - 1)
numberWay = 0;
else
numberWay++;
pos = 0;
}
}
for (int i = beginIndexPos; i < tempBase.length; i++) {
listA.get(numberWay)[posWay[numberWay][0]] = Double.toString(tempBase[i]);
arrayWay[numberWay][posWay[numberWay][0]] = tempBase[i];
posWay[numberWay][0]++;
countIndex++;
}
listA.get(numberWay)[posWay[numberWay][0]] = "'";
return countIndex;
}
public void printIndex() {
for (int i = 0; i < countWay; i++) {
for (int j = 0; j < countElements; j++) {
if (arrayWay[i][j] != null)
System.out.print(arrayWay[i][j]);
}
System.out.println();
}
}
public void printIndexList() {
for (int i = 0; i < countWay; i++) {
for (int j = 0; j < countElements; j++) {
if (listA.get(i)[j] != null)
System.out.print(listA.get(i)[j]);
}
System.out.println();
}
}
public void merger(Double[] base) {
List<String[]> listB = new ArrayList<String[]>();
for (int i = 0; i < countWay; i++) {
listB.add(new String[base.length * 2]);
}
int numberWay = 0;
int[][] posWay = new int[countWay][1];
double lastAdded = 0;
int countSeries = 0;
int[] mem = new int[countWay];
for (int i = 0; i < countWay; i++) {
mem[i] = 0;
}
while (true) {
double tmp = 999999999;
int way = -1;
for (int i = 0; i < countWay; i++) {
if (listA.get(i)[mem[i]] != null) {
String str = listA.get(i)[mem[i]];
if (str.equals("'") && listA.get(i)[mem[i] + 1] != null) {
mem[i]++;
str = listA.get(i)[mem[i]];
}
if (str != null && !str.equals("'")) {
double step = Double.parseDouble(str);
if (tmp >= step) {
tmp = Double.parseDouble(str);
way = i;
}
}
}
}
if (lastAdded > tmp || way == -1) {
listB.get(numberWay)[posWay[numberWay][0]] = "'";
countSeries++;
if (numberWay == countWay - 1) {
numberWay = 0;
} else
numberWay++;
}
if (way == -1) {
break;
}
mem[way]++;
lastAdded = tmp;
listB.get(numberWay)[posWay[numberWay][0]] = Double.toString(tmp);
posWay[numberWay][0]++;
}
listA = listB;
if (countSeries > 1) {
merger(base);
} else {
sortBase = new Double[countElements];
for (int i = 0; i < countWay; i++) {
for (int j = 0; j < countElements; j++) {
if (listA.get(i)[j] != null)
sortBase[j] = Double.parseDouble(listA.get(i)[j]);
}
}
return;
}
}
Double[] array = new Double[10];
for (int i=10; i>0; i--) {
array[10-i] = i;
}
Mergerer merg = new Mergerer(array, 4);
merg.divide();
merg.merger(array);