【问题标题】:Proving mergesort is stable证明归并排序是稳定的
【发布时间】:2017-12-16 06:15:09
【问题描述】:

我写了一个归并排序算法。当我运行以下测试时:

public static void main(String[] args){
    Integer[] arr = {3,7,9,11,0,-5,2,5,8,8,1};
    List<Integer> list = new ArrayList<>();
    list.addAll(Arrays.asList(arr)); // asList() returns fixed size list, so can't pass to mergesort()
    List<Integer> result = mergesort(list);
    System.out.println(result);
  }

我得到[-5, 0, 1, 2, 3, 5, 7, 8, 8, 9, 11],这是正确的。但是,我知道mergesort是一种稳定的排序,那我怎么写一个测试来证明这两个8的顺序是它们原来的顺序呢?

编辑:由于我使用了Integer 类,而不是原始整数,我想我可以得到hashCode(),因为Integer 扩展了基础Object 类。

但是,当我尝试时

Integer[] arr = {3,7,9,11,0,-5,2,5,8,8,1};
System.out.println(arr[8].hashCode());
System.out.println(arr[9].hashCode());

我只得到:

8
8

【问题讨论】:

  • 你不能,用整数。您必须对具有整数属性和另一个唯一属性的对象进行排序。
  • @VasylLyashkevych 怎么可能重复?
  • 它的劳动强度更大,但会创建 Integer EightA = new Integer(8) 等变量。然后您可以将它们在排序后与 == 进行比较,因为它比较引用,即 arr[8] == EightA , arr[9] == 八B 等
  • IntegerhashCode() 是它自己的值,所以你不能用它来区分重复。你需要==,或者System.identityHashCode()

标签: java sorting mergesort


【解决方案1】:

我能想到的最好方法是将数字包装在它们的包装器 Integer 类中。如果您执行以下操作:

Integer eight = new Integer(8);
Integer anotherEight = new Integer(8);

a == b; //Returns false
a.equals(b); //Returns true

否则,按照 cmets 中的建议,您可以在类中添加一个额外的字段以进行比较。

编辑:为了回答您的编辑,Integer.hashcode() 文档指出 hascode 是

等于此 Integer 对象表示的原始 int 值。

【讨论】:

    【解决方案2】:

    我认为使用简单的键值结构,例如thisthat 的一些

    使用这个(简称):

    public class Tuple<X, Y> { 
      public final X x; 
      public final Y y; 
      public Tuple(X x, Y y) { 
        this.x = x; 
        this.y = y; 
      } 
    } 
    

    你可以这样做:

      public static void main(String[] args)
      {
        Integer[] arr = {new Tuple(3,0),new Tuple(7,1),new Tuple(9,2) ,new Tuple(11,3), new Tuple(0,4), new Tuple(-5,5), new Tuple(2,6), new Tuple(5,7), new Tuple(8,8), new Tuple(8,9), new Tuple(1,10)};
        List<Tuple<Integer,Integer>> list = new ArrayList<>();
        list.addAll(Arrays.asList(arr)); // asList() returns fixed size list, so can't pass to mergesort()
        List<Integer> result = mergesort(list);
        System.out.println(result);
      }
    

    并且在归并排序的代码中,只对第一项进行合并,让第二项相同,你应该先看到(8,8),然后是(8,9)

    【讨论】:

      【解决方案3】:

      稳定性证明将涉及分析合并排序算法,而不是创建稳定性测试未失败的测试用例。首先分析自下而上的归并排序可能更简单。首先,将 n 个元素的数组视为长度为 1 的 n 个运行的数组,然后将这些运行重复合并,直到产生单个排序运行。在 k 路归并排序中,如果 k 次运行中的当前元素相等,则将最左边的元素移动到输出数组,保持稳定性。

      对于自上而下的归并排序,通常是 2 路,同样的规则适用,当遇到相等的元素时,从左边运行的元素被移动,保持稳定性。

      【讨论】:

        猜你喜欢
        • 2012-01-03
        • 2019-10-28
        • 2020-02-26
        • 2019-03-15
        • 2017-05-13
        • 2012-05-16
        • 2010-09-11
        • 1970-01-01
        • 2011-06-01
        相关资源
        最近更新 更多