【问题标题】:How can I make this insertion sort method run one step at a time?如何使这种插入排序方法一次运行一步?
【发布时间】:2019-07-24 00:14:59
【问题描述】:

我正在尝试以视觉方式为该方法设置动画,并且我想使用计时器来控制插入排序,方法是让它检查一个索引或每隔一段时间(100 毫秒)交换一组索引。这样我可以看到它一步一步地发挥出来。

方法如下:

public static void sort(int[] arr) {
    for (int i = 1; i < arr.length; i++) {
        int j = i;
        while(j > 0 && arr[j] < arr[j-1]){
            ArrayUtility.swap(j,j-1, arr);
            j--;
        }
    }
}

这样做的目的是,如果一对索引相互检查,该方法不会继续循环,它检查索引然后停止,直到方法的下一部分允许运行 100 毫秒之后。

【问题讨论】:

  • 要么记住你所在的步骤(索引i 和j),然后你可以暂停和继续。或者直接睡在你想要的位置,Thread.sleep(100)。
  • 对于前者,您可以创建一个类Sorter,其中包含int i 和int j 字段和数组。然后这个类提供了一个sortStep() 方法,它只排序一个步骤。因此,它将简单地使用i 和j 字段并执行下一步,然后推进i 和j。

标签: java sorting insertion-sort


【解决方案1】:

说明

记住当前的i 和j 索引,然后您可以通过提取循环构造中所有可能的单步轻松暂停和恢复,即:

  • 常规内循环迭代
  • 内循环已完成,正在推进外循环
  • 外循环已完成,算法完成

我会创建一个类Sorter,其中包含这些索引和数组作为字段,然后您可以提供一个简单的sortStep 方法,它只执行一个步骤并更新索引。


解决方案

public class Sorter {
    private final int[] values;
    private int i = 1;
    private int j = 1;

    public Sorter(int[] values) {
        this.values = values;
    }

    public int[] getValues() {
        return values;
    }

    // @returns Whether sorting algorithm has finished
    public boolean sortStep() {
        if (i >= values.length) {
            // Outer loop has finished
            return true;
        }

        if (j > 0 && values[j] < values[j - 1]) {
            // Inner loop iteration
            ArrayUtility.swap(j, j - 1, values);
            j--;
        } else {
            // Inner loop has finished, outer loop iteration
            i++;
            j = i;
        }
        return false;
    }
}

现在您可以简单地循环调用sortStep 直到完成:

int[] values = ...
Sorter sorter = new Sorter(values);

while (!sorter.sortStep()) {
    // Animate
    displayValues(values);
    Thread.sleep(100);
}

或者将该方法连接到 UI 的一些不错的暂停和恢复按钮。


注意事项

如果你不想治疗

  • 常规内循环迭代
  • 内循环已完成,正在推进外循环

作为两个单独的步骤,但作为一个步骤,您可以简单地将案例移出if-else 构造并在内部迭代后直接执行:

if (j > 0 && values[j] < values[j - 1]) {
    // Inner loop iteration
    ArrayUtility.swap(j, j - 1, avaluesrr);
    j--;
}

if (j <= 0 || values[j] >= values[j - 1]) {
    // Inner loop has finished, outer loop iteration
    i++;
    j = i;
}

同样,您可以将 done-检测放在方法的末尾,以便在方法真正完成时输出 true。这样,您不必再次调用它而没有效果:

// Duplicated at the end of sortStep
if (i >= values.length) {
    // Outer loop has finished
    return true;
}

【讨论】:

    猜你喜欢
    • 2016-01-09
    • 1970-01-01
    • 1970-01-01
    • 2018-10-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-03
    • 2014-10-21
    相关资源
    最近更新 更多