时间复杂度为O(N*logN)的排序算法

归并排序

这里用递归实现了归并排序,左边排序->右边排序->让其整体有序。

让其整体有序的过程中使用了排外序的方法。即构造一个新的数组,比较对i, j所指向的数字进行大小比较,如果arr[i] >arr[j],则将arr[i] 的值复制到新数组中,i + 1,j 不变。这样依次遍历,直到 i 或 j 到达临界点,跳出循环。将剩余部分直接拷贝到新数组中。

根据 master 公式,归并排序的时间复杂度为 O(logN * N),空间复杂度为O(N)。

归并排序的实质

代码实现:

class Sort{
public:

    static void merge(int arr[],int L,int mid,int R){
        int i = L;
        int j = mid + 1;
        int k = 0;
        int *temp_arr = new int(R - L + 1);
        for( ; i <= mid && j <= R; ){
            temp_arr[k++] = arr[i] > arr[j] ? arr[i++] : arr[j++];
        }
        while(i <= mid){
            temp_arr[k++] = arr[i++];
        }
        while(j <= R){
            temp_arr[k++] = arr[j++];
        }
        for(i = L,k = 0; i <= R; i++,k++){
            arr[i] = temp_arr[k];
        }
        delete temp_arr;
    }


    static void mergeSort(int arr[],int L,int R){
        if(L == R)
            return;
        int mid =  L + ((R - L) >> 1);
        cout << mid << endl;
        mergeSort(arr,L,mid);
        mergeSort(arr,mid+ 1,R);
        merge(arr,L,mid,R);
    }

    static void mergeSort(int arr[],int length){
        if(arr == NULL || length <= 0)
            return;
        mergeSort(arr,0,length - 1);
    }
};

例题:

1. 小和问题:一个数组中,每一个数左边比当前数小的数累加起来,叫做这个数组的小和。求一个数组的小和。 例子:[1,3,4,2,5] 1左边比1小的数,没有; 3左边比3小的数,1; 4左 边比4小的数,1、3; 2左边比2小的数,1; 5左边比5小的数,1、3、4、 2; 所以小和为1+1+3+1+1+3+4+2=16

    static int merge(int arr[],int L,int mid,int R){
        int i = L;
        int j = mid + 1;
        int k = 0;
        int res = 0;
        int* temp_arr = new int(R - L + 1);
        for( ; i <= mid && j <= R; ){
            res  += arr[i] < arr[j] ? arr[i] * (R - j + 1) : 0;
            temp_arr[k++] = arr[i] < arr[j] ? arr[i++] : arr[j++];

        }
        while(i <= mid){
            temp_arr[k++] = arr[i++];
        }
        while(j <&
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值