zoukankan      html  css  js  c++  java
  • 归并排序

    归并排序:

    #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;
    }
  • 相关阅读:
    Go strings.Builder
    httprouter使用pprof
    大规模分布式系统的跟踪系统
    Yearning 介绍(SQL审核平台)
    Inception介绍(MySQL自动化运维工具)
    go 学习资源和GitHub库
    go 命令
    Redash 安装部署
    systemd 编写
    查看mysql 版本
  • 原文地址:https://www.cnblogs.com/lzb0803/p/9045343.html
Copyright © 2011-2022 走看看