首页 > 其他分享 >归并排序

归并排序

时间:2025-01-12 10:33:29浏览次数:1  
标签:归并 元素 arr 数组 half 排序

归并排序(Merge Sort)是一种基于分治思想的高效排序算法。它将一个大的数组逐步分解为多个小数组,然后将这些小数组排序后再合并起来,最终得到一个有序的大数组。以下为你详细介绍:

1. 基本原理

  1. 分解:将待排序的数组不断地分成两个大致相等的子数组,直到每个子数组只包含一个元素(单个元素的数组天然有序)。这个过程可以通过递归实现。
  2. 合并:将两个或多个已排序的子数组合并成一个更大的有序数组。合并时,通过比较两个子数组的元素,依次将较小的元素放入结果数组中,直到所有元素都被合并。

2. 算法步骤

  1. 分解步骤
    • 找到数组的中间位置 mid,通常通过 (left + right) // 2 计算得到,其中 left 是数组的起始索引,right 是数组的结束索引。
    • 对左半部分数组 arr[left:mid + 1] 递归调用归并排序。
    • 对右半部分数组 arr[mid + 1:right + 1] 递归调用归并排序。
  2. 合并步骤
    • 创建两个临时数组 left_halfright_half,分别存储左右两个子数组的内容。
    • 使用两个指针 ij 分别指向 left_halfright_half 的起始位置,再使用一个指针 k 指向要合并的目标数组 arr 的起始位置。
    • 比较 left_half[i]right_half[j] 的大小,将较小的元素放入 arr[k] 中,并将相应的指针后移一位。
    • 如果其中一个子数组的元素全部放入 arr 中,将另一个子数组剩余的元素直接复制到 arr 中。

3. 代码实现

以下是Python语言实现归并排序的代码:

def merge_sort(arr):
    if len(arr) <= 1:
        return arr
    mid = len(arr) // 2
    left_half = arr[:mid]
    right_half = arr[mid:]

    left_half = merge_sort(left_half)
    right_half = merge_sort(right_half)

    return merge(left_half, right_half)


def merge(left, right):
    result = []
    i = j = 0
    while i < len(left) and j < len(right):
        if left[i] < right[j]:
            result.append(left[i])
            i += 1
        else:
            result.append(right[j])
            j += 1
    result.extend(left[i:])
    result.extend(right[j:])
    return result

4. 算法分析

  • 时间复杂度
    • 归并排序的分解过程会将数组不断二分,直到每个子数组只有一个元素,这个过程的深度为 \(logn\)。
    • 每层分解的合并操作,都需要对数组中的所有元素进行处理,操作次数为 n
    • 因此,归并排序的时间复杂度在最好、最坏和平均情况下均为 \(O(nlogn)\),其中 n 是数组的长度。
  • 空间复杂度
    • 归并排序在合并过程中需要创建临时数组来存储左右子数组的内容,这需要额外的空间。
    • 空间复杂度主要取决于临时数组的大小,在最坏情况下,临时数组的大小与原数组相同,所以空间复杂度为 \(O(n)\)。
  • 稳定性:归并排序是稳定的排序算法。在合并过程中,当左右子数组中出现相等元素时,先将左边子数组中的元素放入结果数组,这样就保证了相等元素的相对顺序不变。

标签:归并,元素,arr,数组,half,排序
From: https://www.cnblogs.com/codersgl-blog/p/18666749

相关文章

  • 快速排序
    快速排序(QuickSort)是一种高效的排序算法,采用了分治(DivideandConquer)的策略。以下为你详细介绍:1.基本原理从待排序的数据集中选择一个元素作为基准值(pivot)。基准值的选择方法多样,常见的有选择第一个元素、最后一个元素或者中间元素等。重新排列数据集,将所有小于基准值的元......
  • 选择排序
    选择排序(SelectionSort)是一种简单直观的排序算法。它的工作原理是每一趟从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完。以下是选择排序的详细介绍:1.算法步骤初始状态:假设有一个长度为n的数组arr,待排序的元素集合为整......
  • 插入排序
    插入排序(InsertionSort)是一种简单直观的排序算法,它的工作原理类似于扑克牌的整理过程。在摸牌时,玩家会将每张新摸到的牌插入到手中已有的有序牌中的合适位置。1.算法步骤初始状态:将数组分为已排序和未排序两部分。初始时,数组的第一个元素被认为是已排序部分,其余元素是未排序......
  • 拓补排序板子(邻接表实现)
    #include<iostream>#include<vector>usingnamespacestd;constintmaxn=2e5+5;vector<int>graph[maxn];//邻接表voidaddedge(intu,intv){graph[u].emplace_back(v);}intindegree[maxn];//入度表intmain(){intn,m;cin>>n>......
  • 课程表(拓补排序)
    题目链接:https://leetcode.cn/problems/course-schedule-ii/description/题意:给定n门课程,规定只有学完某一个课程才能继续学下一门课程,让你输出学习顺序。如果成环,则返回空数组思路:拓补排序,入度删除法需要提前准备一个indegree数组用来统计每个节点的入度大小,用数组模拟双端......
  • 20250108@Excel(排序问题+文本格式转换+查找多条件的个数)
    1.需求:首行标题需要显示 百分比问题:直接="时间进度:"&E1/E2,显示常规解决方法:使用text函数转换格式2.需求:当需要对某些数值排序时,如果出现相同数值,需要做并列排名问题:使用rank排序会出现中断层排名,如图,2之后是4解决方法:数与数之间进行比较,计算布尔值false的个数。3......
  • php二维数组根据某个字段排序
    1$worderData=[2[3'id'=>1,4'name'=>'张三',5'distance'=>0.1,6......
  • 2.6.桶排序
    桶排序桶排序也是一种非常快的排序算法,但是对于个别数组中某个元素比较大的情况比较费内存。它的实现分为三个步骤:第一步,根据数组创建桶。具体桶的个数取决于数组中元素的大小,所谓桶其实也是一个数组,只不过桶的索引代表数组的元素,而索引值代表在原数组中此元素的个数,例如......
  • 二分+排序
    https://codeforces.com/contest/2053/problem/Dhttps://blog.csdn.net/weixin_61825750/article/details/144799098#include<bits/stdc++.h>#definelcp<<1#definercp<<1|1#defineINF2e9usingnamespacestd;#defineendl'\n'us......
  • 124.【C语言】数据结构之快速排序的小区间优化和非递归的解决方法
    目录1.小区间优化测试代码运行结果2.非递归的解决方法(重要!)递归产生的问题一般来说,递归改非递归有两种方法算法分析递归产生的二叉树栈的示意图先写代码框架再填写细节部分1.小区间优化回顾121.【C语言】数据结构之快速排序(未优化的Hoare排序存在的问题)以及......