深入了解归并排序算法

简介: 深入了解归并排序算法

归并排序(Merge Sort)是一种高效的、基于分治法的排序算法,它的稳定性和性能使其成为常用的排序方法之一。本文将详细介绍归并排序的工作原理,提供示例和Python、Go、Java以及C语言的实现代码。


归并排序的基本思想


归并排序的核心思想是将数组分成两个子数组,递归地对这两个子数组进行排序,然后将它们合并成一个有序数组。这个过程分为以下几个步骤:

1.分割数组: 将待排序的数组分成两个子数组,通常是平均分割。这一步持续递归,直到每个子数组只包含一个元素。

2.递归排序: 递归地对左子数组和右子数组进行排序,直到它们都变成有序数组。

3.合并数组: 将已排序的左子数组和右子数组合并成一个有序数组。合并的过程中,逐个比较左右两个数组的元素,并将较小的元素添加到结果数组中,直到两个数组都为空。

4.返回结果: 最终得到一个完全排序好的数组。


归并排序的关键在于合并过程,也就是如何将两个有序数组合并成一个有序数组。这一过程保持了相等元素的相对顺序,因此归并排序是一种稳定的排序算法。


归并排序的示例


让我们通过一个示例来理解归并排序的工作原理。假设我们有一个整数数组 [5, 2, 9, 3, 4],我们希望按升序排序它。

1.分割数组: 首先将数组分成两个子数组 [5, 2] 和 [9, 3, 4]。

2.递归排序: 分别对左子数组 [5, 2] 和右子数组 [9, 3, 4] 递归地应用归并排序。

对左子数组 [5, 2] 进行归并排序,得到 [2, 5]。

对右子数组 [9, 3, 4] 进行归并排序,得到 [3, 4, 9]。

3.合并数组: 合并已排序的左子数组 [2, 5] 和右子数组 [3, 4, 9]。

比较左右两个数组的首元素,选择较小的元素 2,将其添加到结果数组。

继续比较,选择 3,将其添加到结果数组。

接着选择 4、5、9,按顺序添加到结果数组。

4.返回结果: 最终,得到排序后的数组 [2, 3, 4, 5, 9]。


归并排序的时间复杂度


归并排序的时间复杂度非常稳定,始终为O(n*log(n)),其中n是数组的长度。这使得它适用于大型数据集和对稳定性有要求的情况。


尽管归并排序的时间复杂度相对较高,但它的性能稳定,对于各种数据集都表现出色。此外,归并排序是一种外部排序的重要算法,用于处理大型文件和数据库。


示例代码


以下是归并排序的示例代码,分别使用Python、Go、Java和C语言编写。

Python 归并排序


def merge_sort(arr):
    if len(arr) <= 1:
        return arr
        
    mid = len(arr) // 2
    left = arr[:mid]
    right = arr[mid:]
    
    left = merge_sort(left)
    right = merge_sort(right)
    
    return merge(left, right)
    
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
    
arr = [5, 2, 9, 3, 4]
sorted_arr = merge_sort(arr)
print("排序后的数组:", sorted_arr)


Go 归并排序


package main

import "fmt"

func mergeSort(arr []int) []int {
    if len(arr) <= 1 {
        return arr
    }
    
    mid := len(arr) / 2
    left := arr[:mid]
    right := arr[mid:]
    
    left = mergeSort(left)
    right = mergeSort(right)
    
    return merge(left, right)
}

func merge(left, right []int) []int {
    result := []int{}
    i, j := 0, 0
    
    for i < len(left) && j < len(right) {
        if left[i] < right[j] {
            result = append(result, left[i])
            i++
        } else {
            result = append(result, right[j])
            j++
        }
    }
    
    result = append(result, left[i:]...)
    result = append(result, right[j:]...)
    return result
}

func main() {
    arr := []int{5, 2, 9, 3, 4}
    sorted_arr := mergeSort(arr)
    fmt.Println("排序后的数组:", sorted_arr)
}


Java 归并排序


import java.util.Arrays;

public class MergeSort {
    public static void mergeSort(int[] arr, int left, int right) {
        if (left < right) {
            int mid = (left + right) / 2;
            mergeSort(arr, left, mid);
            mergeSort(arr, mid + 1, right);
            merge(arr, left, mid, right);
        }
    }
    
    public static void merge(int[] arr, int left, int mid, int right) {
        int n1 = mid - left + 1;
        int n2 = right - mid;
        
        int[] leftArray = new int[n1];
        int[] rightArray = new int[n2];
        
        for (int i = 0; i < n1; i++) {
            leftArray[i] = arr[left + i];
        }
        for (int i = 0; i < n2; i++) {
            rightArray[i] = arr[mid + 1 + i];
        }
        
        int i = 0, j = 0;
        int k = left;
        while (i < n1 && j < n2) {
            if (leftArray[i] <= rightArray[j]) {
                arr[k] = leftArray[i];
                i++;
            } else {
                arr[k] = rightArray[j];
                j++;
            }
            k++;
        }
        
        while (i < n1) {
            arr[k] = leftArray[i];
            i++;
            k++;
        }
        
        while (j < n2) {
            arr[k] = rightArray[j];
            j++;
            k++;
        }
    }
    
    public static void main(String[] args) {
        int[] arr = {5, 2, 9, 3, 4};
        mergeSort(arr, 0, arr.length - 1);
        System.out.print("排序后的数组: ");
        System.out.println(Arrays.toString(arr));
    }
}


C 语言 归并排序


#include <stdio.h>

void merge(int arr[], int left, int mid, int right) {
    int n1 = mid - left + 1;
    int n2 = right - mid;
    
    int leftArray[n1], rightArray[n2];
    
    for (int i = 0; i < n1; i++) {
        leftArray[i] = arr[left + i];
    }
    for (int i = 0; i < n2; i++) {
        rightArray[i] = arr[mid + 1 + i];
    }
    
    int i = 0, j = 0, k = left;
    while (i < n1 && j < n2) {
        if (leftArray[i] <= rightArray[j]) {
            arr[k] = leftArray[i];
            i++;
        } else {
            arr[k] = rightArray[j];
            j++;
        }
        k++;
    }
    
    while (i < n1) {
        arr[k] = leftArray[i];
        i++;
        k++;
    }
    
    while (j < n2) {
        arr[k] = rightArray[j];
        j++;
        k++;
    }
}

void mergeSort(int arr[], int left, int right) {
    if (left < right) {
        int mid = left + (right - left) / 2;
        mergeSort(arr, left, mid);
        mergeSort(arr, mid + 1, right);
        merge(arr, left, mid, right);
    }
}

int main() {
    int arr[] = {5, 2, 9, 3, 4};
    int n = sizeof(arr) / sizeof(arr[0]);
    mergeSort(arr, 0, n - 1);
    printf("排序后的数组: ");
    for (int i = 0; i < n; i++) {
        printf("%d ", arr[i]);
    }
    return 0;
}


以上示例代码展示了不同编程语言中的归并排序算法实现。这些示例帮助你理解归并排序的工作原理,并提供了可供参考和使用的代码示例。归并排序是一种稳定且高效的排序算法,适用于各种应用场景,特别适合对大型数据集进行排序。


目录
相关文章
|
6月前
|
机器学习/深度学习 算法 搜索推荐
【初阶算法4】——归并排序的详解,及其归并排序的扩展
【初阶算法4】——归并排序的详解,及其归并排序的扩展
【初阶算法4】——归并排序的详解,及其归并排序的扩展
|
2月前
|
算法 搜索推荐 Shell
数据结构与算法学习十二:希尔排序、快速排序(递归、好理解)、归并排序(递归、难理解)
这篇文章介绍了希尔排序、快速排序和归并排序三种排序算法的基本概念、实现思路、代码实现及其测试结果。
32 1
|
2月前
|
存储 搜索推荐 算法
【排序算法(二)】——冒泡排序、快速排序和归并排序—>深层解析
【排序算法(二)】——冒泡排序、快速排序和归并排序—>深层解析
|
2月前
|
存储 算法 搜索推荐
算法进阶之路:Python 归并排序深度剖析,让数据排序变得艺术起来!
算法进阶之路:Python 归并排序深度剖析,让数据排序变得艺术起来!
79 0
|
7月前
|
算法 前端开发 搜索推荐
前端算法之归并排序
前端算法之归并排序
39 0
|
4月前
|
算法 搜索推荐 Java
算法实战:手写归并排序,让复杂排序变简单!
归并排序是一种基于“分治法”的经典算法,通过递归分割和合并数组,实现O(n log n)的高效排序。本文将通过Java手写代码,详细讲解归并排序的原理及实现,帮助你快速掌握这一实用算法。
46 0
|
4月前
|
数据采集 搜索推荐 算法
【高手进阶】Java排序算法:从零到精通——揭秘冒泡、快速、归并排序的原理与实战应用,让你的代码效率飙升!
【8月更文挑战第21天】Java排序算法是编程基础的重要部分,在算法设计与分析及实际开发中不可或缺。本文介绍内部排序算法,包括简单的冒泡排序及其逐步优化至高效的快速排序和稳定的归并排序,并提供了每种算法的Java实现示例。此外,还探讨了排序算法在电子商务、搜索引擎和数据分析等领域的广泛应用,帮助读者更好地理解和应用这些算法。
48 0
|
5月前
|
存储 算法 搜索推荐
算法进阶之路:Python 归并排序深度剖析,让数据排序变得艺术起来!
【7月更文挑战第12天】归并排序是高效稳定的排序算法,采用分治策略。Python 实现包括递归地分割数组及合并已排序部分。示例代码展示了如何将 `[12, 11, 13, 5, 6]` 分割并归并成有序数组 `[5, 6, 11, 12, 13]`。虽然 $O(n log n)$ 时间复杂度优秀,但需额外空间,适合大规模数据排序。对于小规模数据,可考虑其他算法。**
80 4
|
5月前
|
算法 搜索推荐 C#
|
6月前
|
搜索推荐 算法 Java
Java中的快速排序、归并排序和堆排序是常见的排序算法。
【6月更文挑战第21天】Java中的快速排序、归并排序和堆排序是常见的排序算法。快速排序采用分治,以基准元素划分数组并递归排序;归并排序同样分治,先分割再合并有序子数组;堆排序通过构建堆来排序,保持堆性质并交换堆顶元素。每种算法各有优劣:快排平均高效,最坏O(n²);归并稳定O(n log n)但需额外空间;堆排序O(n log n)且原地排序,但不稳定。
50 3
下一篇
DataWorks