首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >基于CLRS教科书的归并排序

基于CLRS教科书的归并排序
EN

Stack Overflow用户
提问于 2013-01-10 01:43:32
回答 2查看 2.9K关注 0票数 1

下面的代码与CLRS (Corman, Leiserson, Rivest, Stein — 'Introduction to Algorithms')教科书中的合并排序是一致的。

虽然我知道在mergesort()函数中发生了一些错误,但我无法确定正在发生的错误。我认为merge()在功能上是完好无损的。

代码语言:javascript
复制
/* Merge sort as per CLRS */
#include <stdio.h>
#include <stdlib.h>

void merge(int *a,int p,int q,int r){
int n1 = q - p + 1;
int n2 = r - q;
int* l = malloc((n1+1)*sizeof(int));
int* ri = malloc((n2+1)*sizeof(int));
int i,j;
for(i = 0 ; i < n1 ; i++)
    l[i] = a[p+i-1];
for(i = 0 ; i < n2 ; i++)
    ri[i] = a[q+i];
l[n1] = 9999;
ri[n2] = 9999;
i = 0;
j = 0;
int k;
for ( k = p ; k <= r ; k++){
    if( l[i] < ri[j] ){
        a[k] = l[i];
        i++;
    }
    else{
        a[k] = ri[j];
        j++;
    } 
}
}

void mergeSort(int* a,int p,int r){
if( p < r){

    int q = ( p + r ) / 2;
    mergeSort(a,p,q);
    mergeSort(a,p+1,r);
    merge(a,p,q,r);
}

else return;

}

int main(int argc, char* argv[]){
int a[] = {9,21,4,15,1,3};

mergeSort(a,0,5);

int i;
for( i = 0 ; i < 6 ; i++){
    printf("%d ",a[i]);
}
return 0;

}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-01-10 01:49:58

代码语言:javascript
复制
void merge(int *a,int p,int q,int r){
    int n1 = q - p + 1;
    int n2 = r - q;
    int* l = malloc((n1+1)*sizeof(int));
    int* ri = malloc((n2+1)*sizeof(int));
    int i,j;
    for(i = 0 ; i < n1 ; i++)
        l[i] = a[p+i-1];
    for(i = 0 ; i < n2 ; i++)
        ri[i] = a[q+i];

您正在将从索引p-1到索引q-1的元素写到l,将从索引qr-1的元素写到ri。如果为p == 0,则访问越界。

但是,您希望通过r对索引p中的元素进行排序。

代码语言:javascript
复制
void merge(int *a,int p,int q,int r){
    int n1 = q - p + 1;
    int n2 = r - q;
    int* l = malloc((n1)*sizeof(int));
    int* ri = malloc((n2)*sizeof(int));
    int i,j;
    for(i = 0 ; i < n1 ; i++)
        l[i] = a[p+i];
    for(i = 0 ; i < n2 ; i++)
        ri[i] = a[q+i+1];

此外,您还应该检查两个索引ij是否分别小于相应的结束索引n1n2,当其中一个到达其部分的末尾时,将其余部分从另一个部分复制到数组中。如果数组包含较大的条目,则保护值将严重失败。

代码语言:javascript
复制
while(i < n1 && j < n2) {
    if (ri[j] < l[i]) {
        a[k++] = ri[j++];
    } else {
        a[k++] = l[i++];
    }
}
while(i < n1) {
    a[k++] = l[i++];
}
while(j < n2) {
    a[k++] = ri[j++];
}
票数 4
EN

Stack Overflow用户

发布于 2013-01-10 01:52:36

mergeSort()代码中,您拥有:

代码语言:javascript
复制
int q = ( p + r ) / 2;
mergeSort(a,p,q);
mergeSort(a,p+1,r);
merge(a,p,q,r);

我认为第二个mergeSort应该是mergeSort(a, q+1, r);,不是吗?

这与Daniel Fischeranalysis是分开的,也是独立的。

merge()中,您可以分配两个数组。您不能释放这些数组。这是一个内存泄漏。您还应该检查分配是否成功。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14243232

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档