以下代码符合CLRS(Corman, Leiserson, Rivest, Stein — 'Introduction to Algorithms')教科书,该教科书应该进行合并排序。
虽然我知道mergesort()
函数中发生了错误,但我无法确定正在发生的错误。我认为merge()
在功能上完好无损。
/* 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;
}
答案 0 :(得分:3)
在mergeSort()
代码中,您有:
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);
,不应该吗?
这与[{3}} analysis分开并独立于Daniel Fischer。
在merge()
中,您可以分配两个数组。你不释放那些数组。这是内存泄漏。您还应该检查分配是否成功。
答案 1 :(得分:2)
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
的元素,以及从索引q
到r-1
到ri
的元素}。如果p == 0
,则访问越界。
但是,您希望对索引p
到r
中的元素进行排序。
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];
此外,您应该检查两个索引i
和j
是否小于相应的结束索引n1
resp。 n2
,当一个人到达其末尾时,将其余部分的剩余部分复制到数组中。如果数组包含大型条目,则保护值会非常失败。
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++];
}