如何测试排序算法的稳定性?

时间:2019-03-18 23:24:37

标签: java algorithm quicksort mergesort insertion-sort

我目前正在尝试查看我编写的算法是否稳定。我的大多数测试都包括创建一个未排序的整数对象数组,对其进行克隆,在以前的版本上运行我的sort并在要正确排序的数组上运行arrays.sort。基本上,我想知道是否有一种方法可以处理合并,插入和其他实现中的整数对象或其他数据类型的稳定性?证明它也很好,我只是想看看我是否已经写了一个缺陷,因此不稳定。

:任何对象类型都可以正常工作,我只是使用整数来简化测试。

2 个答案:

答案 0 :(得分:2)

通常,当某人想要证明算法的正确性时,他们可以开始尝试通过强归纳法来证明这一点。请注意,任何测试案例都只是针对特定案例的测试。并不能证明您写的内容在所有情况下都是正确的。这就是为什么感应发挥作用的原因。

请阅读https://en.wikipedia.org/wiki/Mathematical_induction 考虑到问题的措辞,我还建议您阅读Algorithms by Sanjoy Dasgupta, Christos H. Papadimitriou, and Umesh Vazirani

编辑: 如果您想证明自己的算法是错误的,那么可以通过证明错误来做到这一点。换句话说,找到算法失败的情况。

您还可以检查所有序列以查找偶数大小的数组,然后检查奇数大小的数组。这将查看预期结果是否适合列表中所有可能的组合。再说一次,当前大小加1或加2的前一种情况如何?这导致归纳。

答案 1 :(得分:0)

由于对象标识存在问题,您将无法使用Integers。

这样的策略可能对您有用-非常简单,只需封装一个整数,排序(我在下面使用Collections.sort()-保证是稳定的)并确保List中的元素对应objs数组中元素的顺序稳定。

public class StableValidation {
    public static void main(String[] args) {
        IntegerWrapper[] objs = new IntegerWrapper[] { new IntegerWrapper(1), new IntegerWrapper(2), new IntegerWrapper(3),
                new IntegerWrapper(2) };

        // sort
        List<IntegerWrapper> list = new ArrayList<>(Arrays.asList(objs));
        Collections.sort(list);

        System.out.println(list.get(1) == objs[1]);
        System.out.println(list.get(2) == objs[3]);
    }
}

class IntegerWrapper implements Comparable<IntegerWrapper> {
    private int i;

    public IntegerWrapper(int i) {
        this.i = i;
    }

    @Override
    public int compareTo(IntegerWrapper that) {
        return Integer.compare(this.i, that.i);
    }
}

收益:

true
true