2014-01-11 37 views
1

我试图修改合并排序以存储原始索引后修改它没有正确排序..我无法找到我出错的地方请帮我找到问题..修改合并排序用于存储原始索引

请在下面找到我的代码。

void merge(int a[][2],int start,int middle ,int end) 
{ 
    int size1 = middle-start +1; 
    int size2 = end-middle; 
    int i,j; 
    int k =start; 
    int L[size1][2]; 
    int R[size2][2]; 
    //int *L = (int *)malloc(sizeof(int)*size1); 
    //int *R = (int *)malloc(sizeof(int)*size2); 

    // copy values from main array to temp arrays 
    for(i=0 ; i<size1; i++) 
    { 
     L[i][1] = a[i+start][1]; 
     L[i][0] = a[i+start][0]; 
    } 
    for(j=0 ; j<size2 ; j++) 
    { 
     R[j][1] = a[j+middle+1][1]; 
     R[j][0] = a[j+middle+1][0]; 
    } 

    i=0; 
    j=0; 
    while(i<size1 && j<size2) 
    { 
     if(L[i] < R[j]) 
     { 
      a[k][1] = L[i][1]; 
      a[k][0] = L[i][0]; 
      k++; 
      i++; 
     } 
     else{ 
      a[k][1] = R[j][1]; 
      a[k][0] = R[j][0]; 
      k++; 
      j++; 
     } 
    } 
    while(i<size1) 
    { 
     a[k][1] = L[i][1]; 
     a[k][0] = L[i][0]; 
     i++; 
     k++; 
    } 
    while(j<size2) 
    { 
     a[k][1] = R[j][1]; 
     a[k][0] = R[j][0]; 
     k++; 
     j++; 
    } 
} 

void mergeSort(int a[][2], int start , int end) 
{ 
    if(start < end) 
    { 
     int middle = start + (end - start) /2; 
     mergeSort(a,start, middle); 
     mergeSort(a,middle+1,end); 
     merge(a,start,middle,end); 
    } 
} 

int main() 
{ 
    int array[10][2] = {{0,55},{1,3},{2,4},{3,5},{4,6},{5,7},{6,8},{7,9},{8,10},{9,2}}; 
    int i; 
    int len = sizeof(array)/sizeof(array[0]) - 1; 
    for(i = 0 ;i <= 9; i++) 
     printf("%d",array[i][1]); 
    mergeSort(array,0,9); 
    printf ("\nArray after sorting:\n") ; 
    printf ("\nindex after sorting:\n") ; 
    for(i = 0 ;i <= 9; i++) 
     printf("%d",array[i][0]); 
    printf ("\nArray after sorting:\n") ; 
    for(i = 0 ;i <= 9; i++) 
     printf("%d",array[i][1]); 
} 
+4

头缩进你的代码,你的第二个问题是解释不清是问题。错误?逻辑? –

+1

世界上谁教导使用“大写 - 单个字母”变量名称,如“L”和“R”? –

+0

i => indexLeft,j => indexRight,k => indexResult,size1 => sizeLeft,size2 => sizeRight,L => arrLeft –

回答

2

你的根本问题是在你的合并算法的初始while循环:

if(L[i] < R[j]) 

这是比较两个int的内存地址[2]数组,而不是值在第二个插槽举行同样,这就是你应该做的。

if(L[i][1] < R[j][1]) 

这就是说,这可以做得相当简单,但这是主要问题的关键。


指针数学版本

为了补充我在这个答案下降了评论,以下是使用指针数学的段代码的简化版本分裂,而不是仅仅索引。仔细查看mergeSort()的递归调用以及参数。还要注意在merge算法使用单个临时数组的索引:

void merge(int a[][2], int mid, int len) 
{ 
    int tmp[len][2]; 
    int i,j,k=0; 

    // copy values from main array to temp 
    memcpy(tmp, a, len*sizeof(*a)); 

    i=0; j=mid; 
    while(i<mid && j<len) 
    { 
     if (tmp[i][1] < tmp[j][1]) 
     { 
      // take from left side 
      a[k][1] = tmp[i][1]; 
      a[k][0] = tmp[i++][0]; 
     } 
     else 
     { // take from right side 
      a[k][1] = tmp[j][1]; 
      a[k][0] = tmp[j++][0]; 
     } 

     ++k; // always incremented 
    } 

    // one of these is skipped. the other will 
    // finish the merge algorithm 
    while(i<mid) 
    { 
     a[k][1] = tmp[i][1]; 
     a[k++][0] = tmp[i++][0]; 
    } 

    while(j<len) 
    { 
     a[k][1] = tmp[j][1]; 
     a[k++][0] = tmp[j++][0]; 
    } 
} 

void mergeSort(int a[][2], int len) 
{ 
    if (len > 1) 
    { 
     int mid = len/2; 
     mergeSort(a, mid); 
     mergeSort(a+mid, len-mid); // note: pointer math for right-segment 
     merge(a, mid, len); 
    } 
} 

int main() 
{ 
    int array[10][2] = {{0,55},{1,3},{2,4},{3,5},{4,6},{5,7},{6,8},{7,9},{8,10},{9,2}}; 
    int i; 
    int len = sizeof(array)/sizeof(array[0]); 
    for(i = 0 ;i < len; i++) 
     printf("%d ",array[i][1]); 

    mergeSort(array, len); 

    printf ("\nIndex after sorting:\n") ; 
    for(i = 0 ;i < len; i++) 
     printf("%d ",array[i][0]); 

    printf ("\nArray after sorting:\n") ; 
    for(i = 0 ;i < len; i++) 
     printf("%d ",array[i][1]); 
} 

输出

55 3 4 5 6 7 8 9 10 2 
Index after sorting: 
9 1 2 3 4 5 6 7 8 0 
Array after sorting: 
2 3 4 5 6 7 8 9 10 55 
+0

现在代码正在工作!我试过了。 –

+0

感谢百万WhozCraig。是的,我现在要使用您建议的其他方法。也非常感谢你找出这个问题。 – user3184719

+0

@ user3184719没问题。您可能还想考虑使用指针数学并将“merge”和“mergeSort”两个参数中的一个去掉。它实际上使得算法更容易,因为减少了使用错误索引的机会(因为你只有两个,'mid'和'end')。无论如何,很高兴它有帮助。 – WhozCraig