java - 了解 Java 中合并排序算法的关键操作计数

标签 java algorithm sorting

我正在评估合并排序算法并对关键操作进行计数。虽然从技术上讲这是家庭作业,但它来自之前的作业,代码是缩小版本,仅显示有问题的区域。我试图更好地理解我的问题并调试我的关键操作计数以准确描述。

该项目是实现合并排序并对其进行评估。关注的领域是计算关键操作并通过随机填充具有 10 个不同大小的数组来确定计数的偏差,每个大小运行 50 次不同的时间(使用不同的随机数据)。我的发现是,对于每个大小,关键操作的数量总是以相同的方式结束(例如,大小为 10 的数组达到 68 个关键操作,而不管数据如何),关键操作偏差为 0。

教授说这是不准确的,我的程序有问题,因为它应该为每个数组长度的不同数据产生不同的计数。我试图弄清楚我的程序中有什么不准确的地方导致了这个问题。我已经检查过每次传递是否产生不同的数组数据,并且这些数据是否被传递给排序算法并正确排序。

下面是我编写的代码,同样,无论数据如何,它仍然会产生相同的关键操作数。谁能指出我的问题?无论我对计数做什么,它总是产生相同的值。

public class MergeSortSingle {
public static int count = 0;

private MergeSortSingle() { }

private static void merge(Comparable[] a, Comparable[] aux, int lo, int mid, int hi) {

    // copy to aux[]
    for (int k = lo; k <= hi; k++) {
        count++;
        aux[k] = a[k]; 
    }

    // merge back to a[]
    int i = lo, j = mid+1;
    for (int k = lo; k <= hi; k++) {
        if      (i > mid) {
            count++;
            a[k] = aux[j++];
        }
        else if (j > hi) {
            count++;
            a[k] = aux[i++];
        }
        else if (less(aux[j], aux[i])) {
            count++;
            a[k] = aux[j++];
        }
        else      {
            count++;
            a[k] = aux[i++];
        }
    }
}

private static void sort(Comparable[] a, Comparable[] aux, int lo, int hi) {
    if (hi <= lo) return;
    int mid = lo + (hi - lo) / 2;
    sort(a, aux, lo, mid);
    sort(a, aux, mid + 1, hi);
    merge(a, aux, lo, mid, hi);
}

public static void sort(Comparable[] a) {
    Comparable[] aux = new Comparable[a.length];
    sort(a, aux, 0, a.length-1);
}

private static boolean less(Comparable v, Comparable w) {
    return v.compareTo(w) < 0;
}

private static void show(Comparable[] a) {
    System.out.println("\nAfter Sorting completed:");
   System.out.print(Arrays.toString(a));
   System.out.println();
}

public static void main(String[] args) {
    int length = 10;
    Comparable[] a = new Comparable[length];
    for (int w = 0; w < length; w++) {
            a[w] = (int) (Math.random() * 10000 + 1);
        }
    System.out.println("Before Sorting:");
    System.out.print(Arrays.toString(a));
    System.out.println();
    MergeSortSingle.sort(a);
    show(a);
    System.out.println("\nCounter = " + count);
}
}

示例输出 1:

排序前: [9661, 4831, 4865, 3383, 1451, 3029, 5258, 4788, 9463, 8971]

排序完成后: [1451, 3029, 3383, 4788, 4831, 4865, 5258, 8971, 9463, 9661]

计数器 = 68

示例输出 2:

排序前: [9446, 230, 9089, 7865, 5829, 2589, 4068, 5608, 6138, 372]

排序完成后: [230, 372, 2589, 4068, 5608, 5829, 6138, 7865, 9089, 9446]

计数器 = 68

合并排序代码来自: http://algs4.cs.princeton.edu/22mergesort/Merge.java.html

最佳答案

您只在合并子数组时计数 - 您使用计数器复制数组 tro aux - 这将始终是相同数量的操作,然后您在 for 处再次使用它循环 - 那里有 4 条路径,每条路径都会递增计数器 - 同样,固定次数。
你还必须在 sort 计算比较- if (hi <= lo) - 这是一个操作。如果失败 - 这是另一个操作。

关于java - 了解 Java 中合并排序算法的关键操作计数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40058707/

相关文章:

java - 配置的 404 错误页面未显示在 JAX-RS 应用程序中

java - 对数组字符串进行排序 java 即输入 ="aab cde abc aaa"输出 ="aaa aab abc cde"

javascript - 如何在一个简单的数组上实现空间 trim

regex - SED 仅在变量、正则表达式使用之间替换空白

java - 如何使用System.arraycopy优化这个方法?

algorithm - 覆盖给定矩形区域所需的最小矩形

algorithm - 有向图 : checking for cycle in adjacency matrix

php - 如何使用 CodeIgniter 进行表格排序?

c# - 从抽象类型对象数组访问特定子类的对象

java - 虽然线程中的循环似乎没有运行