在合并排序中选择中间元素

Selection of middle element in merge sort

本文关键字:中间 元素 选择 合并 排序      更新时间:2023-10-16

对于下面给定的合并排序代码:

void merge(int a[], int bottom, int top, int mid){
    int i = bottom;
    int j = mid+1;
    int k = bottom;
    int c[50];
    while (i <= mid&&j <= top){
         if(a[i]<=a[j]){
         c[k] = a[i];
         i++;
         k++;
         }
     else{
         c[k] = a[j];
         j++;
         k++;
         }
    }
    while (i <= mid){
     c[k] = a[i];
     k++;
     i++;
    }
    while (j <= top){
     c[k] = a[j];
     k++;
     j++;
    }
    for (int i = bottom; i < k; i++){
     a[i] = c[i];   
    }
}
void mergesort(int a[], int bottom, int top){
    if(bottom < top){
     int mid = (bottom+top)/2;
     mergesort(a, bottom, mid);
     mergesort(a, mid+1, top);
     merge(a, bottom, top, mid);
    }
}

如果将合并排序调用更改为

mergesort(a, bottom, mid-1);
mergesort(a, mid, top);

这将导致运行时错误。

从算法方面,我没有看到任何区别。有人能指出这个变化出了什么问题吗?

假设底部为0,顶部为1,因为您调用了mergesort(a, 0, 1)。则mid=(0+1)/2=0。则中间值1=-1。然后您将呼叫mergesort(a, 0, -1)mergesort(a, 0, 1)(注意……这是我们开始的呼叫)。第一个调用将返回,因为它与bottom < top条件不匹配,但第二个调用是无限递归。

如果您注意到,这个问题适用于mergesort(a, n, n + 1)形式的所有调用,并且由于mergesort是一种分而治之类型的算法,因此您将非常频繁地进行此类调用。