简体   繁体   中英

What is wrong with my merge sort code, I can't figure out?

I'm new to programming. I just recently started studying algorithms. My code should just carry out the merge sort procedure but it has some errors although it builds correctly. My code takes input then stops working. It shows this error: 错误

 #include<iostream>
    using namespace std;
    #define size 10
    class mergesort {
    public:
        mergesort(){}
        void merge(int a[]) {
            int mid = 5;
            if (size < 2) return;
            int left[size]; int right[size];
            for (int i = 0; i < mid; i++) {
                left[i] = a[i];
        }
            for (int j = mid; j < size-1; j++) {
                right[j-mid] = a[j];
            }
            merge(left);
            merge(right);
            sort(left, right, a, mid, size-mid);
        }

        void sort(int left[], int right[], int a[], int L, int R) {
            int i = 0; int j = 0; int k = 0;
            while (i < L && j < R) {
                if (left[i] <= right[j])
                {
                    a[k] = left[i];
                    k++; i++;
                }
                else if (right[j] < left[i]) {
                    a[k] = right[j];
                    k++; j++;
                }
            }
            while (i < L) {
                a[k] = left[i];
                k++; i++;
            }
            while (i < R) {
                a[k] = right[j];
                k++; j++;
            }
        }
    };
    void main() {
        mergesort m;
        int a[size];
        cout << "Enter the elements:" << endl;
        for (int i = 0; i < size; i++) {
            cin >> a[size];
        }
        m.merge(a);
    }

The stack overflow error is due to an infinite recursion "loop".

merge() needs two more parameters. In this example, I allocated from stack using _alloca(), so no free is needed. This will only work for arrays small enough to not overflow the stack. The alternative is to use malloc() and free().

    void merge(int a[], int lo, int hi)    // hi is end == last + 1
    {
        if((hi - lo) < 2)
            return;
        int mid = (lo+hi)/2;
        int *left  = _alloca((mid - lo)*sizeof(int));  // alloc from stack
        int *right = _alloca((hi - mid)*sizeof(int));  // alloc from stack
        for (int i = lo; i < mid; i++)
            left[i-lo] = a[i];
        for (int i = mid; i < hi; i++)
            right[i-mid] = a[i];
        merge(left, lo, mid);
        merge(right, mid, hi);
        sort(left, right, a, mid-lo, hi-mid);
        }
    }

The last while in sort() needs to use j instead of i:

        while (j < R) {              // use j here
            a[k] = right[j];
            k++; j++;
        }

Alternative approach - use a one time helper function to do a one time allocation of a second array the same size as a[], perhaps calling it b[], and use the same indexing for b[] as a[] when doing the splitting and merging. b[] would be passed as a parameter to both merge() and sort(), and would be used instead of left[] and right[].

The names are confusing, merge() is really a "sort", and sort() is really a "merge".

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM