多径两相自然平衡合并

时间:2011-11-24 07:56:48

标签: java sorting merge

我有问题。我需要使用java实现multipath两阶段自然平衡合并。我在这里看到了合并排序示例http://www.vogella.de/articles/JavaAlgorithmsMergesort/article.html 我理解它是如何工作的,但我不知道如何实现两阶段合并。一个函数为索引划分数组,第二个是排列合并。它也应该为数组和文件(而不是数组使用的文件)实现。谁知道怎么做?

1 个答案:

答案 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);