【问题标题】:cpp - Implement a merge sort function without using void return type (recursively)cpp - 在不使用 void 返回类型(递归)的情况下实现合并排序功能
【发布时间】:2021-09-03 18:08:56
【问题描述】:

我打算创建一个递归合并排序函数,它返回一个指向已排序数组的指针。下面是我的程序实现。

代码产生的输出主要由垃圾内存位置组成。由于它是一个递归函数,我在调试它时遇到了麻烦。让我害怕的是我是否错误地理解了指针、数组及其相互转换。如果有人可以查看代码并告诉我我的错误,那将非常有帮助。

在给定指向其第一个元素的指针的情况下打印数组的函数

void printArr(int *arr, int n){
    int *ptr = arr;
    for(int i = 0; i < n; i++){
        cout << *ptr << " ";
        ptr++;
    }
    cout << endl;
}

合并排序功能

这里p是给定数组的指针,n是数组的长度。 l 和 r 分别是数组的第一个和最后一个元素的索引。

// returns pointer to the sorted array
int* mergeSort(int *p, int n, int l, int r){
    if(l >= r){
        return &p[l];
    }
    int mid = l + (r-l)/2;
    int *leftArray = mergeSort(p, n, l, mid);
    int *rightArray = mergeSort(p, n, mid+1, r);
    int n1 = mid - l + 1;
    int n2 = r - mid;
    int sortedArray[n1+n2];
    int *ptr = sortedArray; // pointer to the sorted array

    int p1 = 0; // left array index pointer
    int p2 = 0; // right array index pointer
    int idx = 0; // sorted array index pointer
    int flag = 0; /* flag = 1 => all elements of left array have been placed into the sorted array ; flag = 2 => all elements of right array have been placed into the sorted array */

    // putting elements into the sorted array
    for(int i = 0; i < n1+n2; i++){

        if(p1 == n1){
            flag = 1;
            break;
        }
        if(p2 == n2){
            flag = 2;
            break;
        }

        if(*(leftArray+i) > *(rightArray+i)){
            sortedArray[i] = *(leftArray+p1);
            p1++;
            idx++;
        }
        else{
            sortedArray[i] = *(rightArray+p2);
            p2++;
            idx++;
        }
    }

    if(flag == 1){
        // put remaining elements of right array into the sorted array
        for(int i = idx; i < n1+n2; i++){
            sortedArray[i] = *(rightArray+p2);
            p2++;
        }
    }
    if(flag == 2){
        // put remaining elements of left array into the sorted array
        for(int i = idx; i < n1+n2; i++){
            sortedArray[i] = *(leftArray+p1);
            p1++;
        }
    }
    // return the sorted array
    return ptr;
}

主要功能

    int main(){
        int arr[] = {7,2,1,5};
        int n = sizeof(arr)/sizeof(int);
        int *p = arr;
        cout << "Original array: ";
        printArr(arr, n);
        int *f = mergeSort(arr, n, 0, 3);
        cout << "New array: ";
        printArr(f, n);
    }

【问题讨论】:

  • ...您的问题到底是什么?

标签: c++ arrays algorithm recursion mergesort


【解决方案1】:

您的代码返回了本地数组的地址,函数返回后该地址无效。然后打印gabarage数据:

    int sortedArray[n1+n2];
    int *ptr = sortedArray; // pointer to the sorted array

换成

int *ptr = new int[n1 + n2];
auto sortedArray = ptr;

然后我们得到一个非垃圾值,但是我们遇到了内存泄漏并且很难处理内存释放,因为在某些边界条件下,重新调整的指针可能指向数组 p。

所以返回指针不是一个好的设计,它只是浪费了API调用来分配内存和释放内存。最好将函数拆分为两个:第一个分配一个临时缓冲区,第二个处理以缓冲区为参数的排序并使用递归调用自身。或者就地排序,完全避免临时缓冲区。

【讨论】:

    猜你喜欢
    • 2021-04-25
    • 1970-01-01
    • 2011-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-18
    • 1970-01-01
    • 2014-12-14
    相关资源
    最近更新 更多