O(nlogn)排序算法(C++)

版权声明:本文未经允许不得转载 https://blog.csdn.net/weixin_43873349/article/details/87709004

O(nlogn)排序算法(C++)

归并排序

首先进行分解成两部分,之后递归分解,分解到每个单元只有一个数据元素时,不用排序,逐层归并。

    template <typename T>
    void __merge(T arr[], int l, int mid, int r){
        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++;
            }
        }
    }
    
    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);
    }

归并排序的改进一

当遇到近乎有序的待排序序列时,上面的归并排序算法就不如改进式的插入排序算法,因为改进式插入排序算法可以分解到O(n)的时间复杂度,而归并排序本身还是会分解log(n)层级。所以做出改进一,之前是递归排序后,无论如何,直接将两个子序列进行归并,改进为:当前一个序列的最后一个元素比后一个序列的第一个元素还要大时,在进行归并。因为两个子序列都已经有序。

  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);
        if(arr[mid] > arr[mid+1]){
            __merge(arr, l , mid, r);
        }
    }

归并排序的改进二

由于时间复杂度的缘故,当待排序列数量足够小的时候,改进式插入排序算法效率优于归并排序算法,所以在递归终止条件上进行改进。即在正常的归并排序基础上,当待排序列数量在一定小的数量范围之内用改进式插入排序。

template <typename T>
void insertionSort2(T arr[], int l, int r){
   for(int i = l+1; i <= r; i++){
       T e = arr[i];
       int j;
       for(j = i; j > l; j--){
           if(arr[j-1] > e){
               arr[j] = arr[j-1];
           }else{
               break;
           }
       }
       arr[j] = e;
   }
}

template <typename T>
void __mergeSort(T arr[], int l, int r){
   /*if(l >= r){
       return;
   }*/
   if(r-l <= 15){
       insertionSort2(arr, l, r);
       return;
   }
   int mid = (l + r) / 2;
   __mergeSort(arr, l, mid);
   __mergeSort(arr, mid+1, r);
   if(arr[mid] > arr[mid+1]){
       __merge(arr, l , mid, r);
   }
}

猜你喜欢

转载自blog.csdn.net/weixin_43873349/article/details/87709004