Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/323.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 您如何证明或说明快速合并排序是一种不稳定的算法?_Java_Algorithm_Mergesort_Array Algorithms - Fatal编程技术网

Java 您如何证明或说明快速合并排序是一种不稳定的算法?

Java 您如何证明或说明快速合并排序是一种不稳定的算法?,java,algorithm,mergesort,array-algorithms,Java,Algorithm,Mergesort,Array Algorithms,当我阅读《算法》第四版第2章中的问题2.2.10时,一个问题让我感到困惑。书上说快速合并算法的结果不稳定,我找不到证据。帮帮我,谢谢 public static void sort(Comparable[] a, int lo, int hi){ if hi <= lo { return; } int mid = lo + (hi - lo) / 2; sort(a, lo, mid); sort(a, mid+1, hi); mer

当我阅读《算法》第四版第2章中的问题2.2.10时,一个问题让我感到困惑。书上说快速合并算法的结果不稳定,我找不到证据。帮帮我,谢谢

public static void sort(Comparable[] a, int lo, int hi){
    if hi <= lo {
    return;
    }
    int mid = lo + (hi - lo) / 2;
    sort(a, lo, mid);
    sort(a, mid+1, hi);
    merge(a, lo, mid, hi);
}

// Why is the result of this sort not stable
private static void merge(Comparable[] a, int lo, int mid, int hi) { 
   for (int i = lo; i <= mid; i++)
      aux[i] = a[i]; 

   for (int j = mid+1; j <= hi; j++)
      aux[j] = a[hi-j+mid+1];

   int i = lo, j = hi; 
   for (int k = lo; k <= hi; k++) 
      if (less(aux[j], aux[i])) a[k] = aux[j--];
      else                      a[k] = aux[i++];
}
公共静态无效排序(可比[]a,int-lo,int-hi){

如果hi将“相等”元素保持在相同顺序的排序算法被认为是稳定的。因此,不稳定意味着:您有多个相等的元素,当您对整个列表/数组进行排序时,该排序的输出将以不同的顺序显示这些相等的元素(可能)

例如,假设您有一个Person类,并且实现了相等,以便只查看姓氏,而忽略名字

现在,假设您有两个Person对象,分别表示“John Doe”和“Jane Doe”。它们按顺序在未排序的列表中

稳定的意思是:你总是以“约翰·多伊”出现在“简·多伊”之前而告终。如果是不稳定的类型,你就没有这种保证

换句话说:您需要创建一个至少有两个属性的类。然后您需要定义
compareTo()
以仅依赖这两个属性中的一个

然后创建该类对象的示例列表,然后进行足够长的实验,直到找到一个示例,其中排序列表显示相等的对象改变了顺序

换句话说:创建一个列表(p1,p2,p3,p4,…),对其进行排序,然后寻找一个可能会显示……p4,p3……的结果,尽管p4和p3被认为是“相等的”

最后:对于使用一些基于属性的测试框架,这实际上是一个非常好的用例,例如。使用这样的框架,您需要:

  • 创建一个“生成器”,该生成器可以创建您稍后排序的某个类的“随机”对象(您可以倾斜生成器以确保从中获得一组“相等”的对象)
  • 然后让框架测试底层的“断言”,即排序前后“相等”对象的顺序不得更改

然后让框架发挥它的魔力…

证明排序算法不稳定只需要找到一个失败。证明排序算法稳定更复杂。检查失败的一种方法是使用一个整数数组并将整数分成两部分,上面的8位为伪随机值,下面的24位为al到整数的索引(0到count-1)。然后运行排序,仅使用较高的8位进行比较,例如在C中:

    if((b[j]&0xff000000) < (b[i]&0xff000000)) ...
if((b[j]&0xff000000)<(b[i]&0xff000000))。。。
排序完成后,使用所有32位检查数组是否有序

使用这种方法,我能够确认合并排序的这种变化是不稳定的

显然,这被称为“快速”合并排序的原因是,在进行合并时,没有检查运行的结束。左运行按从lo到mid的正向顺序复制到aux[],而右运行按从hi到mid+1的反向顺序复制到aux[]。然后合并从两端(lo和hi)开始,并朝中间运行(mid和mid+1),左跑使用i从lo向前跑到mid,右跑使用j从hi向后跑到mid+1。由于没有检查到达跑步终点,i可能会增加到mid以上(潜在稳定性问题),或者j可能会减少到mid+1以下(不是稳定性问题).如果i的增量大于mid,并且原始右行中最高的两个元素aux[mid+1]==aux[mid+2],则稳定性会被破坏。在这种情况下,元素按相反顺序复制

尽管本书称之为“快速合并排序”,但它可以更快地避免在aux中复制数据,而是根据递归级别更改合并方向。对于自上而下,这可以通过在递归调用中复制一种类型并交换数组引用来完成,例如以下wiki示例:

可以使用一对相互递归的函数来避免初始副本,一个以a[]结尾,另一个以b[]结尾


稍微快一点的是自底向上的合并排序,因为它跳过了堆栈上索引的所有递归拆分和存储。在这种情况下,合并的方向基于合并过程。为了保持过程数相等,可以提前检查奇数的过程计数,并在开始第一个b之前交换元素对OtTo-Up合并排序传递。

< P>为了证明算法的不稳定性,一个反例就足够了:让我们考虑将4个元素的数组排序为<代码> A BC D < /代码>,该代码与<代码>小于< /代码>谓词比较。

  • 排序(a,0,3)
    在2个子数组上递归:
  • 排序(a,0,1)
    再次递归
  • 立即返回的排序(a,0,0)
  • 立即返回的排序(a,1,1)
  • merge(a,0,0,1)
    不会更改
    ab
  • 排序(a,2,3)
  • 立即返回的排序(a,2,2)
  • 立即返回的排序(a,3,3)
  • merge(a,2,2,3)
    不会改变
    cd
  • merge(a,0,1,3)
    将项目
    a B C D
    a B D C
    的顺序复制到
    t
    ,然后合并循环中的所有比较计算为false,因此复制回
    a
    的元素的顺序相同,从
    t[i++]
    A B D C
    ,证明排序算法的不稳定性,即:比较相等的元素的相对顺序没有保留

好的,那么我的答案应该说明你在家庭作业上取得进步所需要的一切。如果你需要更多信息,请给我留言,否则请考虑