【问题标题】:Counting array operations in a Shell sort used for Integer arrays在用于整数数组的 Shell 排序中计数数组操作
【发布时间】:2018-06-09 16:10:57
【问题描述】:

我正在尝试计算在我接受整数数组的 Shell 排序方法中发生的数组操作的数量(分配到/输出数组,以及与数组元素的比较)。

这是我的 Shell 排序正在使用的代码

 public static <T extends Comparable<? super T>> void shellSort(T[] a) {
    int gap = a.length / 2;
    while (gap >= 1) {
        if (gap % 2 == 0) {
            ++gap;
        }
        for (int i = gap; i < a.length; ++i) {
            int p = i;
            numAsgn++;
            T temp = a[p];
            numComp++;
            while (p >= gap && a[p - gap].compareTo(temp) > 0) {
                numAsgn++;
                a[p] = a[p - gap];
                p -= gap;
            }
            numAsgn++;
            a[p] = temp;
        }
        if (tracing) {
            System.out.println("...gap=" + gap + ": " + Arrays.toString(a));
        }
        gap /= 2;
    }
}

这是我期待的输出。

(注意:我对其他排序方法执行相同的操作,但这与我的问题无关)

我的 shell 排序得到的输出:

因此,我得出结论,我错过了在某处更新numComp 的值,但我不知道它在我的代码中的位置。 任何帮助表示赞赏。

此外,我尝试将计数更改为这种方式。但无济于事。

//numComp++;
            while (p >= gap && a[p - gap].compareTo(temp) > 0) {
                numComp++;
                numAsgn++;
                a[p] = a[p - gap];
                p -= gap;
            }

我不明白这是怎么可能的,因为循环会多次更新numComp++,但这里的数字要低得多。

【问题讨论】:

  • 数组是否排在最后?
  • @NiVeR 是的。但我只是打印出在方法完成后在整个方法循环中更新的值。最后我什至没有存储排序后的数组。
  • 根据我的计算25是错误的,正确答案应该是24。
  • 你是怎么得出这个结论的?你能告诉我如何正确更新我的值以获得 24 吗?我的教授提供了包含 25 的示例输出。如果他的号码有误,我可能不得不联系他@NiVeR
  • 检查答案。

标签: java arrays sorting shellsort


【解决方案1】:

试试这个:

.....
T temp = a[p];
numComp++;
boolean in = false;
while (p >= gap && a[p - gap].compareTo(temp) > 0) {
    if(in) numComp++;
    in = true;
    numAsgn++;
    a[p] = a[p - gap];
    p -= gap;
}
.....

关键是不要在外部比较中计算两次

然后是部分:

if (gap % 2 == 0) {
    ++gap;
}

这里好像不对,没必要,删掉就好了。

完整代码为:

public static <T extends Comparable<? super T>> void shellSort(T[] a) {
    int gap = a.length / 2;
    int numAsgn = 0, numComp = 0;
    while (gap >= 1) {
        for (int i = gap; i < a.length; ++i) {
            int p = i;
            numAsgn++;
            T temp = a[p];
            numComp++;
            boolean in = false;
            while (p >= gap && a[p - gap].compareTo(temp) > 0) {
                if (in)
                    numComp++;
                in = true;
                numAsgn++;
                a[p] = a[p - gap];
                p -= gap;
            }
            numAsgn++;
            a[p] = temp;
        }
        gap /= 2;
    }
    System.out.println(numComp + "," + numAsgn);
}

【讨论】:

  • 输出结果是21。我以为你说的是​​24? @NiVeR
  • 您的代码也有错误,请检查更新。
  • 删除后仍然是 22。实际上,这不是我的代码。这是我教授的
  • 我现在给你完整的功能,我写的。为了简短起见,我删除了一些打印语句。
  • #COMP 给了我 24 分,#ASGN 给了我 54 分。这是不正确的:(
【解决方案2】:
        numComp++; // comparing perhaps more than once but only counted as once here
        while (p >= gap && a[p - gap].compareTo(temp) > 0) { // this loop will result in multiple comparisons, is it not?
            numAsgn++;
            a[p] = a[p - gap];
            p -= gap;
        }

由于需要直接解决,我们分别记录内部比较,然后将其添加到 total 比较计数器如下:

        numComp++; // for the loop termination comparison;
        int innerComp = 0; // for the loop non-termination comparison;
        while (p >= gap && a[p - gap].compareTo(temp) > 0) {
            innerComp++;
            numAsgn++;
            a[p] = a[p - gap];
            p -= gap;
        }
        numComp += innerComp;

【讨论】:

  • 你没有提供解决方案。
  • @Hearen 我尝试了您的解决方案,它最终给出了 30 作为 #COMP 的数量。这是不正确的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-03-26
  • 1970-01-01
  • 1970-01-01
  • 2019-08-21
  • 2013-02-11
  • 2011-07-09
  • 1970-01-01
相关资源
最近更新 更多