Mergesort implementation is slow

前端 未结 1 713
情话喂你
情话喂你 2020-12-21 11:48

I\'am doing a report about different sorting algorithms in C++. What baffles me is that my mergesort seems to be slower than heapsort in both of th

相关标签:
1条回答
  • 2020-12-21 12:21

    The example merge sort is doing allocation and copying of data in merge(), and both can be eliminated with a more efficient merge sort. A single allocation for the temp array can be done in a helper / entry function, and the copy is avoided by changing the direction of merge depending on level of recursion either by using two mutually recursive functions (as in example below) or with a boolean parameter.

    Here is an example of a C++ top down merge sort that is reasonably optimized. A bottom up merge sort would be slightly faster, and on a system with 16 registers, a 4 way bottom merge sort a bit faster still, about as fast or faster than quick sort.

    // prototypes
    void TopDownSplitMergeAtoA(int a[], int b[], size_t ll, size_t ee);
    void TopDownSplitMergeAtoB(int a[], int b[], size_t ll, size_t ee);
    void TopDownMerge(int a[], int b[], size_t ll, size_t rr, size_t ee);
    
    void MergeSort(int a[], size_t n)       // entry function
    {
        if(n < 2)                           // if size < 2 return
            return;
        int *b = new int[n];
        TopDownSplitMergeAtoA(a, b, 0, n);
        delete[] b;
    }
    
    void TopDownSplitMergeAtoA(int a[], int b[], size_t ll, size_t ee)
    {
        if((ee - ll) == 1)                  // if size == 1 return
            return;
        size_t rr = (ll + ee)>>1;           // midpoint, start of right half
        TopDownSplitMergeAtoB(a, b, ll, rr);
        TopDownSplitMergeAtoB(a, b, rr, ee);
        TopDownMerge(b, a, ll, rr, ee);     // merge b to a
    }
    
    void TopDownSplitMergeAtoB(int a[], int b[], size_t ll, size_t ee)
    {
        if((ee - ll) == 1){                 // if size == 1 copy a to b
            b[ll] = a[ll];
            return;
        }
        size_t rr = (ll + ee)>>1;           // midpoint, start of right half
        TopDownSplitMergeAtoA(a, b, ll, rr);
        TopDownSplitMergeAtoA(a, b, rr, ee);
        TopDownMerge(a, b, ll, rr, ee);     // merge a to b
    }
    
    void TopDownMerge(int a[], int b[], size_t ll, size_t rr, size_t ee)
    {
        size_t o = ll;                      // b[]       index
        size_t l = ll;                      // a[] left  index
        size_t r = rr;                      // a[] right index
        while(1){                           // merge data
            if(a[l] <= a[r]){               // if a[l] <= a[r]
                b[o++] = a[l++];            //   copy a[l]
                if(l < rr)                  //   if not end of left run
                    continue;               //     continue (back to while)
                while(r < ee)               //   else copy rest of right run
                    b[o++] = a[r++];
                break;                      //     and return
            } else {                        // else a[l] > a[r]
                b[o++] = a[r++];            //   copy a[r]
                if(r < ee)                  //   if not end of right run
                    continue;               //     continue (back to while)
                while(l < rr)               //   else copy rest of left run
                    b[o++] = a[l++];
                break;                      //     and return
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题