专题:归并排序

专题:归并排序

简介

归并排序是一种$ Nlog(N) $时间复杂度的排序算法, 其主要使用了分治的思想,是一种不稳定排序算法。

归并排序法主要由以下3个阶段组成:

  • 划分(split):将大的数组从中间进行切分,分为两个长度接近的子数组;

  • 递归排序(sort):递归处理2个子数组;

  • 归并(merge):将已经排序好的2个子数组的各个元素进行比较合并到新的大数组中,得到大的有序数组;

特点

  • 归并排序在归并阶段会调整(交换)元素的相对位置,所以是一种不稳定的排序算法;

  • 归并排序中,需要一个新的数组保存归并后的数组,因此需要额外的$ N $空间;

使用

  • 归并排序在处理区间问题中有很广泛的使用,主要原因在于归并阶段

算法模板

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
/// 归并排序
fn merge_sort(nums: &mut Vec<i64>, left: usize, right: usize) {
    // 无法继续切分时,退出递归
    if right - left <= 1 {
        return;
    }

    // 切分子序列
    let mid = (left + right) >> 1;

    // 递归处理
    merge_sort(nums, left, mid);
    merge_sort(nums, mid, right);

    //进行左右两侧元素比较处理
    //

    // 合并已处理过的子序列
    let left_nums = nums[left..mid].to_vec();
    let right_nums = nums[mid..right].to_vec();
    let (mut l, mut r) = (0, 0);
    let mut i = left;
    while l < left_nums.len() && r < right_nums.len() {
        if left_nums[l] < right_nums[r] {
            nums[i] = left_nums[l];
            l += 1;
        } else {
            nums[i] = right_nums[r];
            r += 1;
        }
        i += 1;
    }
    while l < left_nums.len() {
        nums[i] = left_nums[l];
        l += 1;
        i += 1;
    }
    while r < right_nums.len() {
        nums[i] = right_nums[r];
        r += 1;
        i += 1;
    }
}

相关题目

updatedupdated2024-08-252024-08-25