分治(并归)排序算法

【说明】

采用归并排序对 n 个元素进行递增排序时,首先将 n 个元素的数组分成各含/2 个元素的两个子数组,然后用归并排序对两个子数组进行递归排序,最后合并两个已经排好序的子数组得到排序结果。
下面的 C 代码是对上述归并算法的实现,其中的常量和变量说明如下:

  • A:待排序数组
    
  • l,c,r:一个子数组的位置为从 l 到 c,另一个子数组的位置为从 c+1 到 r
    
  • arr_l_size,arr_r_size:两个子数组的长度
    
  • L,R:临时存放待合并的两个子数组
    
  • i,j,k:循环变量
    

【代码实现】

#include <limits.h>
#include <stdio.h>

void merge(int A[], int l, int c, int r) {
    int arr_l_size = c - l + 1; // 左边数组的大小
    int arr_r_size = r - c; // 左边数组的大小
    int i, j, k;
    int L[50], R[50];

    for (i = 0; i < arr_l_size; i++) {
        L[i] = A[l + i];
    }

    for (j = 0; j < arr_r_size; j++) {
        R[j] = A[c + j + 1];
    }

    L[arr_l_size] = INT_MAX;
    R[arr_r_size] = INT_MAX;

    i = 0;
    j = 0;

    for (k = l; k < r + 1; k++) {
        if (L[i] < R[j]) {
            A[k] = L[i];
            i++;
        } else {
            A[k] = R[j];
            j++;
        }
    }


    for (int s = 0; s < r + 1; s++) {
        printf("%d", A[s]);
    }
    printf("\n");
}

void mergerSort(int A[], int l, int r) {
    int c;
    if (l < r) {
        c = (l + r) / 2;
        mergerSort(A, l, c);
        mergerSort(A, c + 1, r);
        merge(A, l, c, r);
    }
}

//  0       1       2    |    3         4       5       6
//  l               c    |   c+1                r     length
//  2       5       6    |    1         4       7

// L[] = {2, 5, 6}          R[] = {1, 4, 7}

int main() {
    int A[] = {2, 5, 6, 1, 4, 7};
    int length = sizeof(A) / sizeof(int);
    mergerSort(A, 0, length - 1);
    printf("排序后的数组:");
    for (int i = 0; i < length; i++) {
        printf("%d", A[i]);
    }
    return 0;
}

【算法分析】

递归式:T(n)=2T(n/2)+O(n)
时间复杂度:O(nlgn)
空间复杂度:O(n)
posted @ 2023-03-16 10:25  云の彼端  阅读(61)  评论(0)    收藏  举报