基础算法改进——归并排序的改进

基础算法改进——归并排序的改进

简介:
在这里插入图片描述

改进方案:
1.小区间采用插入排序(原因:小区间内元素有序的概率较大,)
2.待比较两区间元素间已经有序,直接返回(区间内部肯定是已经有的,这是归并的原理)
** 2.1** 正序:前子序列的最大值<=后子序列的最小值,直接返回
** 2.2** 逆序:后子序列的最大值<=前子序列的最小值,先复制后子序列,再复制前子序列。
3.临时数组的有效利用
4:不递归:
** 4.1**:用栈模拟递归,即用自定义的栈来模拟系统栈的递归过程从而避免递归
** 4.2**:递推,即把通常的归并过程反过来实现,自下而上不断合并,首先定义一个长度初始为1,然后不断以这个长度为单位分割数组并两两合并,一轮结束以后长度乘以二,不断重复上述过程直至该长度大于数组实际长度。
5:原地归并(空间复杂度为O(1))
在这里插入图片描述

改进前代码:

//CC_MergeSort.cpp
int* Tmp = new int[1000000];

template<class T>
void CC_MergeSort(T* begin,int Len)//归并排序
{ 
    if (!Len) return;
    T* A = begin;
    int mid =  Len / 2, i = 0, j = mid + 1, k = 0;
    
    CC_MergeSort(&A[0], mid);
    CC_MergeSort(&A[mid + 1], Len - mid - 1);
    while (i <= mid && j <= Len)
        if (A[i] <= A[j])
            Tmp[k++] = A[i++];
        else
            Tmp[k++] = A[j++];

    while (i <= mid)
        Tmp[k++] = A[i++];
    while (j <= Len)
        Tmp[k++] = A[j++];
    for (int l = 0; l <= Len; l++)
        A[l] = Tmp[l];
}

利用方案一改进:

void CC_InsertSort(T* begin, int Len)
{
    T t,* A = begin;
    int i,j;
    for (i = 1; i <= Len; i++)
        if (A[i] < A[i - 1]) {
            t = A[i];
            for (j = i - 1; j >= 0 && A[j] > t; j--)
                    A[j + 1] = A[j];
            A[j+1] = t;

        }
}

//在Merge内:
 if (Len < 15) { //小区间采用插入排序
        CC_InsertSort(A, Len);
        return;
    }

利用方案二改进:

 if (A[mid] < A[mid + 1])//前子序列的最大值<=后子序列的最小值,直接返回
            return;
        if (A[Len] < A[0]) {//后子序列的最大值<=前子序列的最小值,先复制后子序列,再复制前子序列。
            while (j <= Len)
                Tmp[k++] = A[j++];
            while (i <= mid)
                Tmp[k++] = A[i++];
            for (int l = 0; l <= Len; l++)
                A[l] = Tmp[l];
            return;
        }

前两个方案修改后整体的代码:

#include <iostream>
#include <time.h>
int* Tmp = new int[1000000];


template<class T>//插入排序
void CC_InsertSort(T* begin, int Len)
{
    T t,* A = begin;
    int i,j;
    for (i = 1; i <= Len; i++)
        if (A[i] < A[i - 1]) {
            t = A[i];
            for (j = i - 1; j >= 0 && A[j] > t; j--)
                    A[j + 1] = A[j];
            A[j+1] = t;

        }
}

template<class T>
void CC_MergeSort(T* begin,int Len)//归并排序
{ 
    if (!Len) return;
    T* A = begin;
    int mid =  Len / 2, i = 0, j = mid + 1, k = 0;
    
    CC_MergeSort(&A[0], mid);
    CC_MergeSort(&A[mid + 1], Len - mid - 1);

    if (Len < 15) { //小区间采用插入排序
        CC_InsertSort(A, Len);
        return;
    }
 
    while (i <= mid && j <= Len) {
        if (A[mid] < A[mid + 1])//前子序列的最大值<=后子序列的最小值,直接返回
            return;
        if (A[Len] < A[0]) {//后子序列的最大值<=前子序列的最小值,先复制后子序列,再复制前子序列。
            while (j <= Len)
                Tmp[k++] = A[j++];
            while (i <= mid)
                Tmp[k++] = A[i++];
            for (int l = 0; l <= Len; l++)
                A[l] = Tmp[l];
            return;
        }

        if (A[i] <= A[j])
            Tmp[k++] = A[i++];
        else
            Tmp[k++] = A[j++];
    }
       

    while (i <= mid)
        Tmp[k++] = A[i++];
    while (j <= Len)
        Tmp[k++] = A[j++];
    for (int l = 0; l <= Len; l++)
        A[l] = Tmp[l];
}
posted @ 2022-03-05 16:00  Cheney822  阅读(145)  评论(0编辑  收藏  举报