如何使这种插入排序方法一次运行一个步骤?

时间:2019-03-01 23:03:29

标签: java sorting insertion-sort

我正在尝试对该方法进行动画处理,我想使用一个计时器来控制插入排序,方法是让它每隔一段时间(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--;
        }
    }
}

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

1 个答案:

答案 0 :(得分:0)

说明

记住当前的ij索引,然后您可以随时提取所有可能的单步操作,轻松地暂停和恢复,即循环:

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

我将创建一个类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;
}

类似地,您可以将完成检测放置到方法的末尾,以在方法真正完成时输出方法true。这样,您无需再次调用就不会产生任何作用:

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