归并排序(Merge Sort)

一、基本介绍

归并排序是一种分治思想的经典排序算法,它将原序列分成若干个子序列,通过递归再将序列合并起来。根据分治的思想,归并排序的时间复杂度始终稳定在 O(nlogn)。

二、算法描述

归并排序算法可以描述为分为两步:分离和归并。

1. 分离

为了使归并排序可以递归地运行,需要将原序列分割成若干子序列,使得每个子序列的长度均为1,即子序列不可再分。然后将子序列两两合并,合并后的序列长度为2,继续两两合并,以此类推,直到合并成原序列。

void merge_sort(int arr[], int left, int right)
{
    if (left >= right) return;

    int mid = left + (right - left) / 2;

    merge_sort(arr, left, mid);
    merge_sort(arr, mid + 1, right);

    merge(arr, left, mid, right);
}

2. 归并

归并是指将已经排好序的两个子序列合并成一个序列的过程。在合并的过程中,需要使用一个临时数组来保持排序的结果,最终将临时数组内容复制回原数组。

void merge(int arr[], int left, int mid, int right) 
{
    int temp[right - left + 1];
    int i = left, j = mid + 1, k = 0;

    while (i <= mid && j <= right)
    {
        if (arr[i] <= arr[j])
            temp[k++] = arr[i++];
        else
            temp[k++] = arr[j++];
    }

    while (i <= mid)
        temp[k++] = arr[i++];

    while (j <= right)
        temp[k++] = arr[j++];

    for (i = left, k = 0; i <= right; ++i, ++k)
        arr[i] = temp[k];
}

三、优化方法

归并排序算法的关键在于归并过程,因此如何优化归并过程对算法的性能影响较大。以下是几种常见的优化方法:

1. 优化归并过程

对于一些小规模数组,直接使用插入排序。经过实验,如果数组长度为16以下时,插入排序的效率更高。

void merge_sort(int arr[], int left, int right)
{
    if (left + 16 >= right)
    {
        insert_sort(arr + left, right - left + 1);
        return;
    }

    int mid = left + (right - left) / 2;

    merge_sort(arr, left, mid);
    merge_sort(arr, mid + 1, right);

    merge(arr, left, mid, right);
}

2. 避免重复申请空间

归并过程需要一个临时数组来保存排序好的元素,但是每次递归都会申请一个新的数组,这样会浪费空间。因此,在函数开始时申请一次空间即可,然后在递归的过程中直接使用同一个数组。

void merge_sort(int arr[], int left, int right, int temp[])
{
    if (left >= right) return;

    int mid = left + (right - left) / 2;

    merge_sort(arr, left, mid, temp);
    merge_sort(arr, mid + 1, right, temp);

    merge(arr, left, mid, right, temp);
}

void merge(int arr[], int left, int mid, int right, int temp[]) 
{
    // 省略
}

3. 使用尾递归优化

尾递归优化可以避免递归调用带来的栈空间开销。在归并排序中,递归调用发生在分离两个子序列的过程中。这里采用尾递归优化方法,将递归过程转换为循环过程,可以避免递归调用的栈空间开销。

void merge_sort(int arr[], int left, int right, int temp[])
{
    while (left > 1);

        merge_sort(arr, left, mid, temp);
        left = mid + 1;
    }
}

void merge(int arr[], int left, int mid, int right, int temp[]) 
{
    // 省略
}

四、总结

归并排序虽然有些优化方法,但它的时间复杂度始终稳定在 O(nlogn),并且适用于各种数据类型的排序,因此在实际应用中仍然有广泛的应用。

原创文章,作者:CRGYF,如若转载,请注明出处:https://www.506064.com/n/332001.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
CRGYFCRGYF
上一篇 2025-01-20 14:10
下一篇 2025-01-20 14:10

相关推荐

  • sort()的应用及实现原理

    一、sort()基本介绍 sort()方法是在JavaScript中对数组进行排序的一种常用方法,它可以按照一定的规则将数组中的元素按照升序或降序排列。sort()方法有两种应用方…

    编程 2025-04-24
  • Git merge –no-ff详解

    Git是一款非常强大的版本管理工具,可以有效地管理项目的版本更新。Git merge –no-ff命令是其中的一种操作,可以在合并分支时保留分支信息和历史记录。本文将从…

    编程 2025-04-23
  • 深入理解 Linux sort 命令

    一、概述 Linux sort 命令是一个强大的排序工具,它可以将文件内容按照用户指定的排序规则排序。 sort 命令默认按照字典序升序排序,但用户可以通过参数实现自定义排序规则。…

    编程 2025-04-12
  • JS数组排序方法sort

    在JS中,数组作为一种常见的数据类型,提供了许多方便的操作方式。其中,排序是常见的一种操作,而sort方法也成为了JS中处理数组排序的基本方法。 一、JS数组排序方法 在JavaS…

    编程 2025-01-21
  • 深度剖析std::sort

    一、简介 std::sort是C++ STL的一个排序算法,它可以按照一定规则对一个给定的数组、向量或迭代器范围内的元素进行排序。std::sort是非稳定排序算法,平均时间复杂度…

    编程 2025-01-20
  • PHP sort()函数的用法与使用注意事项

    PHP sort()函数是一个非常重要也非常常用的函数,它可以对一个数组进行升序排列。在开发过程中,我们常常需要对数组进行排序,而sort()函数会在这个过程中起到非常重要的作用。…

    编程 2025-01-16
  • PHP sort()函数的用法与使用注意事项

    PHP sort()函数是一个非常重要也非常常用的函数,它可以对一个数组进行升序排列。在开发过程中,我们常常需要对数组进行排序,而sort()函数会在这个过程中起到非常重要的作用。…

    编程 2025-01-16
  • 使用Python中的sort函数进行列表排序

    一、sort函数介绍 sort函数是Python内置的一个函数,用于对列表进行排序,对于包含数字或字符串元素的列表,sort函数都可以进行比较和排序。sort函数的用法非常简单,只…

    编程 2025-01-16
  • sort头文件的详细阐述

    一、sort头文件的名称 sort头文件是C++的STL库中的头文件之一,其主要作用是为数组或容器提供排序的功能。sort本质上是一种排序算法,其名称来源于英语单词“sort”,意…

    编程 2025-01-16
  • Java ArrayList Sort

    Java中的ArrayList类是一个可变数组的实现,它提供了数组的所有功能,同时还支持动态增加和删除元素的能力。在实际开发中,ArrayList常常用于存储一组元素,这些元素可能…

    编程 2025-01-16

发表回复

登录后才能评论