归并排序算法实现和分析

归并排序是一种基于分治策略的排序算法,它将数组不断分割成两半,直到每个子数组只有一个元素,然后使用辅助数组进行合并,按顺序将元素重新组合到原数组中。文章提供了Java和Python两种语言的代码实现,并分析了算法的时间复杂度为O(nlogn)。
摘要由CSDN通过智能技术生成

归并排序

算法思想

归并排序的算法思想和快排一样都是分治的思想,将长度为n的数组每次分一半,直到不能再分为止,然后使用一个新的数组来作为中转数组,将分成小块的数组以中间索引值为界限,比较值的大小,将值较小的先放进中转数组中,指针后移,将下一个数和上一次较大的数继续比较,重复此过程,直到到达中间索引,之后把剩下的数组中的数全部挪到中转数组中,最终把中转数组的值赋给原数组。

图片演示

img

img

代码实现

java

public static void mergeSort(int[] arr,int left,int right,int[] temp){
        if (left < right){
            int mid = (left+right) / 2;
            mergeSort(arr,left,mid,temp);
            mergeSort(arr,mid+1,right,temp);
            merge(arr,left,right,mid,temp);
        }
    }
    //合并的方法

    /**
     *
     * @param arr
     * @param left 左边有序序列的初始索引
     * @param right 右边索引
     * @param mid 中间索引
     * @param temp 做中转的数组
     */
    public static void merge(int[] arr,int left,int right,int mid,int[] temp){
        int i = left;
        int j = mid+1;
        int t = 0;
        //2 4 8 9 6 5 4
        //0 1 2 3 4 5 6
        //1
        while (i <= mid && j <= right){
            if (arr[i] >= arr[j]){
                temp[t] = arr[j];
                j += 1;
                t += 1;
            }else {
                temp[t] = arr[i];
                i += 1;
                t += 1;
            }
        }
        //2
        while (i <= mid){
            temp[t] = arr[i];
            i += 1;
            t += 1;
        }
        while (j <= right){
            temp[t] = arr[j];
            j += 1;
            t += 1;
        }
        //3
        t = 0;
        int tempLeft = left;
        while (tempLeft <= right){
            arr[tempLeft] = temp[t];
            t += 1;
            tempLeft += 1;
        }
    }

python


def mergeSort(nums,left,right,temp):
    if left < right:
        mid = (left + right) // 2
        #递归处理左子列表
        mergeSort(nums,left,mid,temp)
        #递归处理右子列表
        mergeSort(nums,mid+1,right,temp)
        #合并
        merge(nums,left,right,mid,temp)

def merge(nums,left,right,mid,temp):
    #用来操作数组的索引
    l = left
    r = mid+1
    t = 0
    #依次比较,将值小的先放进去
    while l <= mid and r <= right:
        if nums[l] < nums[r]:
            temp[t] = nums[l]
            l += 1
            t += 1
        else:
            temp[t] = nums[r]
            r += 1
            t += 1
    #将剩余数组挪进去
    while l <= mid:
        temp[t] = nums[l]
        l += 1
        t += 1
    while r <= right:
        temp[t] = nums[r]
        t += 1
        r += 1
    #将中转数组的值赋值给原数组
    t = 0
    tempLeft = left
    while tempLeft <= right:
        nums[tempLeft] = temp[t]
        t += 1
        tempLeft += 1


nums = [8,4,5,7,1,3,6,2]
temp = [_ for _ in range(len(nums))]
mergeSort(nums,0,len(nums)-1,temp)
print(nums)


算法分析

归并排序使用的是分治的算法思想,将一个规模为n的问题分成两个规模为n/2的子问题,由下图的递归树可得最终分成了n个时间花费为c的子问题,此二叉树的深度为logn,所以最终的算法复杂度是O(nlogn)
在这里插入图片描述

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值