概念

归并排序就是将数组划分成多个子数组,然后对子数组进行排序,再反向合并。这用到了递归,所以最后的子数组是一个元素,然后再进行合并,合并的过程中,两个操作数组已经是有序的了,所以用两个指针分别指向各自的元素,然后将指向目标中较小(较大)的元素作为合并数组的第一个,然后移动指针,依次执行,就能得到一个排好序的数组了

伪代码

merge_sort(A):
  if numberof(A) > 1 then
    B <- A[0:n/2]
    C <- A[n/2+1:n]
    merge_sort(B)
    merge_sort(C)
    merge(B, C, A)
  
merge(B, C, A):
  p = 0 // 指向 B
  q = 0 // 指向 C
  i = 0 // 结果数组 A 的索引

  while p < len(B) && q < len(C) do
    if B[p] <= C[q] then
      A[i++] = B[p++] // 取 B 中较小的元素
    else 
      A[i++] = C[q++] // 取 C 中较小的元素

  if p < len(B) then
    copy(B[p:], A, i) // 复制 B 中剩余的元素到 A
  
  if q < len(C) then
    copy(C[q:], A, i) // 复制 C 中剩余的元素到 A

代码实现

C

#include <stdio.h>

static void merge(int arr[], size_t left, size_t mid, size_t right)
{
    int p = left, q = mid + 1;
    int idx = 0;
    int res[right - left + 1];

    while (p <= mid && q <= right) {
        if (arr[p] <= arr[q])
            res[idx++] = arr[p++];
        else
            res[idx++] = arr[q++];
    }

    while (p <= mid) res[idx++] = arr[p++];
    while (q <= right) res[idx++] = arr[q++];

    for (int i = left; i <= right; i++)
        arr[i] = res[i - left];
}

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

static void print(int arr[], size_t size)
{
    for (size_t i = 0; i < size; i++)
        printf(" %d", arr[i]);
    printf("\n");
}

int main(void)
{
    int arr[] = {4, 5, 7, -1, 2, 4, 0};
    size_t size = sizeof(arr) / sizeof(arr[0]);
    print(arr, size);

    merge_sort(arr, 0, size - 1);
    print(arr, size);

    return 0;
}

Lua

local function merge(arr, left, mid, right)
    local p, q = left, mid + 1
    local res = {}

    while p <= mid and q <= right do
        if arr[p] <= arr[q] then
            res[#res+1] = arr[p]
            p = p + 1
        else
            res[#res+1] = arr[q]
            q = q + 1
        end
    end

    while p <= mid do
        res[#res+1] = arr[p]
        p = p + 1
    end

    while q <= right do
        res[#res+1] = arr[q]
        q = q + 1
    end

    for i = left, right, 1 do
        arr[i] = res[i - left + 1]
    end
end

local function merge_sort(arr, left, right)
    if left < right then
        local mid = math.floor((left + right) / 2)
        merge_sort(arr, left, mid)
        merge_sort(arr, mid + 1, right)
        merge(arr, left, mid, right)
    end
end

local function print(arr)
    for _, v in ipairs(arr) do
        io.write(" " .. tostring(v))
    end
    io.write("\n")
end

local function run()
    local arr = {9, 4, 5, 7, -2, -1, 0}
    print(arr)

    merge_sort(arr, 1, #arr)
    print(arr)
end

run()
 posted on 2025-03-13 12:03  Dylaris  阅读(24)  评论(0)    收藏  举报