• 归并排序


    归并排序:

    #include <iostream>
    #include "SortTestHelper.h"
    #include "InsertionSort.h"
    
    using namespace std;
    
    
    // 将arr[l...mid]和arr[mid+1...r]两部分进行归并
    template<typename T>
    void __merge(T arr[], int l, int mid, int r) {
    
        // 经测试,传递aux数组的性能效果并不好
        T aux[r - l + 1];
        for (int i = l; i <= r; i++)
            aux[i - l] = arr[i];
    
        int i = l, j = mid + 1;
        for (int k = l; k <= r; k++) {
    
            if (i > mid) {
                arr[k] = aux[j - l];
                j++;
            }
            else if (j > r) {
                arr[k] = aux[i - l];
                i++;
            }
            else if (aux[i - l] < aux[j - l]) {
                arr[k] = aux[i - l];
                i++;
            }
            else {
                arr[k] = aux[j - l];
                j++;
            }
        }
    }
    
    // 递归使用归并排序,对arr[l...r]的范围进行排序
    template<typename T>
    void __mergeSort(T arr[], int l, int r) {
    
        if (l >= r)
            return;
    
        int mid = (l + r) / 2;
        __mergeSort(arr, l, mid);
        __mergeSort(arr, mid + 1, r);
        __merge(arr, l, mid, r);
    }
    
    template<typename T>
    void mergeSort(T arr[], int n) {
    
        __mergeSort(arr, 0, n - 1);
    }
    int main() {
    
        int n = 50000;
    
        // 测试1 一般性测试
        cout<<"Test for Random Array, size = "<<n<<", random range [0, "<<n<<"]"<<endl;
        int* arr1 = SortTestHelper::generateRandomArray(n,0,n);
        int* arr2 = SortTestHelper::copyIntArray(arr1, n);
    
        SortTestHelper::testSort("Insertion Sort", insertionSort, arr1, n);
        SortTestHelper::testSort("Merge Sort",     mergeSort,     arr2, n);
    
        delete[] arr1;
        delete[] arr2;
    
        cout<<endl;
    
    
    Test for Random Array, size = 50000, random range [0, 50000]
    Insertion Sort : 3.173 s
    Merge Sort : 0.012 s
    
    
        // 测试2 测试近乎有序的数组
        int swapTimes = 100;
        cout<<"Test for Random Nearly Ordered Array, size = "<<n<<", swap time = "<<swapTimes<<endl;
        arr1 = SortTestHelper::generateNearlyOrderedArray(n,swapTimes);
        arr2 = SortTestHelper::copyIntArray(arr1, n);
    
        SortTestHelper::testSort("Insertion Sort", insertionSort, arr1, n);
        SortTestHelper::testSort("Merge Sort",     mergeSort,     arr2, n);
    
        delete(arr1);
        delete(arr2);
    
    Test for Random Nearly Ordered Array, size = 50000, swap time = 100
    Insertion Sort : 0.008 s
    Merge Sort : 0.008 s
    
    
        return 0;
    }

    归并排序优化:

    // 递归使用归并排序,对arr[l...r]的范围进行排序
    template<typename T>
    void __mergeSort2(T arr[], int l, int r){
    
        // 对于小规模数组,使用插入排序
        if( r - l <= 15 ){
            insertionSort(arr, l, r);
            return;
        }
    
        int mid = (l+r)/2;
        __mergeSort2(arr, l, mid);
        __mergeSort2(arr, mid+1, r);
        // 对于arr[mid] <= arr[mid+1]的情况,不进行merge
        // 对于近乎有序的数组非常有效,但是对于一般情况,有一定的性能损失
        if( arr[mid] > arr[mid+1] )
            __merge(arr, l, mid, r);
    }
    
    template<typename T>
    void mergeSort2(T arr[], int n){
        __mergeSort2( arr , 0 , n-1 );
    }

    优化后的测试:

    int main() {
    
        int n = 50000;
    
        // 测试1 一般性测试
        cout<<"Test for Random Array, size = "<<n<<", random range [0, "<<n<<"]"<<endl;
        int* arr1 = SortTestHelper::generateRandomArray(n,0,n);
        int* arr2 = SortTestHelper::copyIntArray(arr1, n);
        int* arr3 = SortTestHelper::copyIntArray(arr1, n);
    
        SortTestHelper::testSort("Insertion Sort", insertionSort, arr1, n);
        SortTestHelper::testSort("Merge Sort",     mergeSort,     arr2, n);
        SortTestHelper::testSort("Merge Sort 2",   mergeSort2,    arr3, n);

    Test for Random Array, size = 50000, random range [0, 50000]
    Insertion Sort : 3.181 s
    Merge Sort : 0.012 s
    Merge Sort 2 : 0.011 s

    delete[] arr1;
        delete[] arr2;
        delete[] arr3;
    
        cout<<endl;
    
    
        // 测试2 测试近乎有序的数组
        int swapTimes = 10;
        cout<<"Test for Random Nearly Ordered Array, size = "<<n<<", swap time = "<<swapTimes<<endl;
        arr1 = SortTestHelper::generateNearlyOrderedArray(n,swapTimes);
        arr2 = SortTestHelper::copyIntArray(arr1, n);
        arr3 = SortTestHelper::copyIntArray(arr1, n);
    
        SortTestHelper::testSort("Insertion Sort", insertionSort, arr1, n);
        SortTestHelper::testSort("Merge Sort",     mergeSort,     arr2, n);
        SortTestHelper::testSort("Merge Sort 2",   mergeSort2,    arr3, n);

    Test for Random Nearly Ordered Array, size = 50000, swap time = 10
    Insertion Sort : 0.001 s
    Merge Sort : 0.007 s
    Merge Sort 2 : 0.002 s

    delete[] arr1;
        delete[] arr2;
        delete[] arr3;
    
        return 0;
    }
  • 相关阅读:
    使用 Windows XP 的两种强大的工具在您的代码中检测并堵塞 GDI 泄漏
    SystemParametersInfo
    SQL bcp命令详解
    不同版本操作系统和数据库的之间链接,和操作
    js添加删除行和双击变文本框
    MYSQL 日志问题
    循环文件夹下的文件
    php导出数据到EXCEL
    配置Apache服务器的二级域名支持
    每天读一遍,坚持30天,和老外交流没问题!
  • 原文地址:https://www.cnblogs.com/lzb0803/p/9045343.html
Copyright © 2020-2023  润新知