【问题标题】:Undesired behaviour in MergeSort functionMergeSort 函数中的不良行为
【发布时间】:2021-01-18 00:40:08
【问题描述】:

我是编程新手,我正在尝试在我的程序中实现合并排序功能,但它无法正常工作。我翻遍了代码,但找不到问题。

例如,如果 6 元素数组的用户输入是:3 2 4 1 6 7

输出为:1 3 2 4 32708 32708

有人可以帮助我吗?另外,如果有人对改进我的编码风格有任何建议,将不胜感激。谢谢。

#include <stdio.h>
#include <stdlib.h>

int main(void) {
    int *a, n;

    a = malloc(100 * sizeof(int)); // dynamically allocating memory for original array

    if (a == NULL)
        return 1;

    printf("Enter n of elements in the array:");

    scanf("%i", &n); // n of elements the in array

    printf("Enter elements:\n");

    for (int i = 0; i < n; i++) {
        scanf("%i", &a[i]); // prompt user for input elements
    }

    int f, l, m, n1, n2; // declaring variables

    f = 0;               // first element
    l = n - 1;           // last element
    m = (f + l) / 2;     // mid point
    n1 = m + 1 - f;      // n elements l1
    n2 = l - m;          // n elements l2

    int l1[n1];          // temp array 1
    int l2[n2];          // temp array2

    for (int i = 0; i < n1; i++) {
        l1[i] = a[i];    // copy elements into temp l1
    }
    for (int j = 0; j < n2; j++) {
        l2[j] = a[m + 1 + j]; // copy elements into temp l2
    }

    int i, j, k; // variable for arrays index

    i = 0;
    j = 0;
    k = 0;

    //sorting and copying elements in original array

    while (i < n1 && j < n2) {
        if (l1[i] <= l2[j]) { // if element l1 smaller or equal to l2 element
            a[k] = l1[i];     // copy element l1 into original array
            i++;              // increment l1
        } else {              // if element l1 bigger than l2
            a[k] = l2[j];     // copy element l2 into original array
            j++;              // increment l2
        }
        k++; // increment original array
    }

    // copy remaining elements (if any)
    while (i < n1) {
        a[k] = l1[i];
        i++;
        k++;
    }

    while (j < n2) {
        a[k] = l2[i];
        j++;
        k++;
    }

    printf("Your sorted array:\n");

    for (int d = 0; d < n; d++) {
        printf("%i ", a[d]); // print sorted array
    }

    printf("\n");

    free(a); // freeing original array
}

【问题讨论】:

  • I/O 工作应该在与归并排序算法不同的函数中。 I/O 可以保留在main(),但您需要一个单独的mergesort() 函数来对数组进行排序。对于 100 个元素,实际上不需要使用 malloc() — 只需在 main() 中本地声明数组即可。如果数组大小达到 1 MB 左右,那么您将停止使用本地数组,但在此之前,没有必要仅仅因为大小而进行动态分配。您应该检查用户没有尝试将 200 个数字添加到您的 100 元素数组中。

标签: c sorting merge mergesort


【解决方案1】:

您需要递归合并。你只写了合并部分,没有写递归排序函数。

更多信息:https://www.geeksforgeeks.org/merge-sort/

#include <stdio.h>
#include <stdlib.h>

void merge(int arr[], int l, int m, int r) 
{ 
    int i, j, k; 
    int n1 = m - l + 1; 
    int n2 = r - m; 
  
    /* create temp arrays */
    int L[n1], R[n2]; 
  
    /* Copy data to temp arrays L[] and R[] */
    for (i = 0; i < n1; i++) 
        L[i] = arr[l + i]; 
    for (j = 0; j < n2; j++) 
        R[j] = arr[m + 1 + j]; 
  
    /* Merge the temp arrays back into arr[l..r]*/
    i = 0; // Initial index of first subarray 
    j = 0; // Initial index of second subarray 
    k = l; // Initial index of merged subarray 
    while (i < n1 && j < n2) { 
        if (L[i] <= R[j]) { 
            arr[k] = L[i]; 
            i++; 
        } else { 
            arr[k] = R[j]; 
            j++; 
        } 
        k++; 
    } 
  
    /* Copy the remaining elements of L[], if there are any */
    while (i < n1) { 
        arr[k] = L[i]; 
        i++; 
        k++; 
    } 
  
    /* Copy the remaining elements of R[], if there are any */
    while (j < n2) { 
        arr[k] = R[j]; 
        j++; 
        k++; 
    } 
} 

void mergeSort(int arr[], int l, int r) 
{ 
    if (l < r) { 
        // Same as (l+r)/2, but avoids overflow for 
        // large l and h 
        int m = l + (r - l) / 2; 
  
        // Sort first and second halves 
        mergeSort(arr, l, m); 
        mergeSort(arr, m + 1, r); 
  
        merge(arr, l, m, r); 
    } 
}

int main(void)
{
    int *a, n;

    printf("Enter n of elements in the array:");
    scanf("%i", &n); //n of elements the in array

    a = malloc(n * sizeof(int)); //dynamically allocating memory for original array
    if (a == NULL)
        return 1;

    printf("Enter elements:\n");

    for (int i = 0; i < n; i++) {
        scanf("%i", &a[i]); //prompt user for input elements
    }
    
    mergeSort(a, 0, n - 1);
    
    printf("Your sorted array:\n");

    for (int d = 0; d < n; d++) {
        printf("%i ", a[d]); //print sorted array
    }
    printf("\n");

    free(a); //freeing original array
    return 0;
}

【讨论】:

  • 我明白了,谢谢 Jacob。是否有一个排序函数不是递归完成的?只是为了更清楚地了解“幕后”的实际编码。
  • 我冒昧地修复了数组分配并简化了对mergeSort()的初始调用。
猜你喜欢
  • 2021-12-21
  • 2020-05-22
  • 1970-01-01
  • 2012-09-22
  • 2015-02-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多