java - 归并排序问题

标签 java mergesort

一些背景:

可以说,我们的老师基本上坐下来用 Java 进行了 SQL 的基本实现。他告诉我们尝试在他制作的这个系统中实现合并算法。

我正在尝试进行合并排序(自上而下的实现),但有一些问题。

合并排序应该采用两个表(从他制作的数据库实现中模拟)并排列它们,以便它们按升序(1-8)从最低到最高显示。

该代码允许我使用我们老师编写的 DbIterator 来迭代表及其内容。所以我们有两个表,其中包含以下数据:

[hello1, 5]
[hello2, 6]
[hello3, 7]
[hello4, 8]

另一个表:

[goodbye4, 4]
[goodbye2, 2]
[goodbye3, 3]
[goodbye1, 1]

合并排序后应该打印出以下内容:

[goodbye1, 1]
[goodbye2, 2]
[goodbye3, 3]
[goodbye4, 4]
[hello1, 5]
[hello2, 6]
[hello3, 7]
[hello4, 8]

但这就是它打印出来的内容:

null
[hello1, 5]
[hello2, 6]
[hello3, 7]

我对此感到有点困惑,并尝试调试以找出问题所在,但我可能尝试了太多,以至于对实际问题视而不见。所以这是代码(排序发生在最后三个方法上):

public String[] MergeSort(String table1, String table2) {
    DbIterator scannerA = getTableScanner(table1);
    DbIterator scannerB = getTableScanner(table2);
    HashMap<Integer, String> records = new HashMap<>();
    ArrayList<Integer> A = new ArrayList<>();
    ArrayList<Integer> B = new ArrayList<>();
    int n = 0;
    scannerA.open();
    while(scannerA.hasNext()) {
        Record r = scannerA.next();
        StringField sF = (StringField) r.getField(0);
        IntegerField iF = (IntegerField) r.getField(1);
        records.put(iF.hashCode(), sF.toString());
        A.add(iF.hashCode());
        n++;
    }
    scannerA.close();

    scannerB.open();
    while(scannerB.hasNext()) {
        Record r = scannerB.next();
        StringField sF = (StringField) r.getField(0);
        IntegerField iF = (IntegerField) r.getField(1);
        records.put(iF.hashCode(), sF.toString());
        B.add(iF.hashCode());
        n++;
    }
    scannerB.close();

    int[] mergeResult;
    int[] aA = convertIntegers(A);
    int[] bB = convertIntegers(B);
    mergeResult = TopDownSplitMerge(aA, 0, n, bB);
    String[] results = new String[mergeResult.length];
    for(int v = 0; v < mergeResult.length; v++) {
        if(records.containsKey(v)) {
            results[v] = "[" + records.get(v) + ", " + v +"]";
        }
    }

    return results;
}

private int[] CopyArray(int[] B, int iBegin, int iEnd, int[] A) {
    for(int k = iBegin; k < iEnd; k++)
        A[k] = B[k];
    return A;
}

private int[] TopDownSplitMerge(int[]A,int iBegin, int iEnd, int[]B) {
    if(iEnd - iBegin < 2) {
        return null;
    }
    int iMiddle = (iEnd + iBegin) / 2;
    TopDownSplitMerge(A, iBegin, iMiddle, B);
    TopDownSplitMerge(A, iMiddle, iEnd, B);
    TopDownMerge(A, iBegin, iMiddle, iEnd, B);
    int[] tmp = CopyArray(B, iBegin, iEnd, A);
    return tmp;
}

public void TopDownMerge(int[] A, int iBegin, int iMiddle, int iEnd, int[] B) {
    int i0 = iBegin;
    int i1 = iMiddle;

    for(int j = iBegin; j < iEnd; j++) {
        if(i0 < iMiddle && (i1 >= iEnd || A[i0] <= A[i1])) {
            B[j] = A[i0++];
        } else {
            B[j] = A[i1++];
        }
    }
}

首先,这不是我个人的算法,而是我试图从 wiki 实现它。我唯一不明白的部分是他们所说的“iEnd”,这可能会解决整个问题。值n。我不知道如何计算或者给出什么值。可能真的是整个问题。

最佳答案

读取TopDownMerge - 将A数组的两个排序部分中的项目合并到B的相应部分,然后CopyArray 将合并的数据复制回 A。所以B只是一个合并数据的临时缓冲区,而不是数据源。您不应使用两个输入数组 aAbB 调用 TopDownSplitMerge,而是将它们连接成一个数组并将该数组用作 A 参数(以及另一个数组作为 B 缓冲区)。

关于java - 归并排序问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22489380/

相关文章:

java - 如何以编程方式检测 Databricks 环境

c++ - 如何在 C++ 和归并排序中比较字符串

c++ - 合并排序给出奇怪的答案

java - 与字符串的合并排序

java - 为 Spring 配置 Weblogic 11g

JAVA解析txt文件中的数据

java - 在多个线程中划分合并排序算法

由于堆栈溢出,迭代合并排序的 C++ 实现在输入大时崩溃

javascript - 从 SQlite 中提取 Lat Long 并显示在 webview 上

java - JavaMelody 和 ab 中的 tomcat 性能监控