归并排序




def merge(arr,tempArr,left,mid,right):
    # 标记左半区第一个未排序的元素
    l_pos = left
    # 标记右半区第一个未排序的元素
    r_pos = mid + 1
    # 临时数组元素的下标
    pos = left
    # 合并
    while l_pos <= mid and r_pos<=right:
        if arr[l_pos] < arr[r_pos]:     # 左半区第一个剩余元素更小
            tempArr[pos] = arr[l_pos]
            pos=pos+1
            l_pos=l_pos+1
        else:                           # 右半区第一个剩余元素更小
            tempArr[pos] = arr[r_pos]
            pos+=1
            r_pos+=1
    # 合并 左半区剩余元素
    while l_pos<=mid:
        tempArr[pos] = arr[l_pos]
        pos=pos+1
        l_pos=l_pos+1

    # 合并 右半区剩余元素
    while r_pos<=right:
        tempArr[pos] = arr[r_pos]
        pos=pos+1
        r_pos = r_pos+1

    # 把临时数组中合并后的元素复制回原来的数组
    while left<=right:
        arr[left] = tempArr[left]
        left=left+1


def msort(arr,temp,left,right):
    # 如果只有一个元素,那么就不需要继续划分
    # 只有一个区域,本身就是有序的,只需要被归并即可
    if left<right:
        # 找中间点
        mid = (left+right)//2
        # 递归划分左半区
        msort(arr,tempArr,left,mid)
        #  递归划分左半区
        msort(arr,tempArr,mid+1,right)
        # 合并已经排序的部分
        merge(arr,tempArr,left,mid,right)




if __name__ == '__main__':
    arr = [9,5,2,7,12,4,3,1,11]
    tempArr = [0]*len(arr)
    res = msort(arr,tempArr,0,len(arr)-1)
    print(res)
    print(arr)

java版本

package leetcode.mySort;

public class MergeSort {
    /**
     * 归并排序核心思想:将数组不断从中间划分,知道划分到一个元素,然后对临近的数组两两进行合并,合并原则就是遍历两个有序数组,从小到大的放到新数组里面

     * 1.划分
     * 2.两两排序合并
     * 3.覆盖原始值
     * @param args
     */

    private static void msort(int[] arr, int[] tempArr, int left, int right) {
        //如果只有一个元素,那么就不需要继续划分
        //只有一个区域,本身就是有序的,只需要被归并即可
        if(left<right){
            // 找中间点
            int mid = (left+right)/2;
            // 递归划分左半区
            msort(arr,tempArr,left,mid);
            msort(arr,tempArr,mid+1,right);
            merge(arr,tempArr,left,mid,right);
        }
    }

    private static void merge(int[] arr, int[] tempArr, int left, int mid, int right) {
        // 合并的两个区域中,左半区域的第一个未排序元素
        int l_pos = left;
        // 合并的两个区域中,右半区域的第一个未排序元素
        int r_pos = mid+1;
        // 临时数组元素下标
        int pos = left;

        // 合并
        while (l_pos<=mid && r_pos<=right){
            if (arr[l_pos]<arr[r_pos]){
                tempArr[pos] = arr[l_pos];
                l_pos++;
            }else {
                tempArr[pos]= arr[r_pos];
                r_pos++;
            }
            pos++;
        }

        // 合并 左半区
        while (l_pos<=mid){
            tempArr[pos] = arr[l_pos];
            pos++;
            l_pos++;
        }

        // 合并右半区
        while (r_pos<=right){
            tempArr[pos] = arr[right];
            pos++;
            r_pos++;
        }

        // 把临时数组中合并后的元素复制到原来的数组
        while (left<=right){
            arr[left] = tempArr[left];
            left++;
        }
    }


    public static void main(String[] args) {
        int[] arr = {9,5,2,7,12,4,3,1,11};
        //
        int[] tempArr = new int[arr.length];
        msort(arr,tempArr,0,arr.length-1);
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }
    }

}

参考:https://www.bilibili.com/video/BV1Na411e7Vg?from=search&seid=1605882729834734327&spm_id_from=333.337.0.0&vd_source=46d50b5d646b50dcb2a208d3946b1598
https://www.bilibili.com/video/BV1Pt4y197VZ?from=search&seid=1605882729834734327&spm_id_from=333.337.0.0&vd_source=46d50b5d646b50dcb2a208d3946b1598

作者:静默虚空
欢迎任何形式的转载,但请务必注明出处。
限于本人水平,如果文章和代码有表述不当之处,还请不吝赐教。

posted @   Chenyi_li  阅读(22)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示