归并排序-(C语言实现)

#include 
#include 

/**整体思想:分治 + 递归*/

// 归并两个已经有序的数组,L、M和R分别是左边界、分界点和右边界
// 这里将右边数组的第一个元素的下标作为了分界点
void merge(int array[], int L, int M, int R) {
    // 求出左右两部分数组的大小
    int LEFT_SIZE = M - L;
    int RIGHT_SIZE = R - M + 1;
    // 分别定义左右两个数组存放原数组中左右两边的数据
    int left[LEFT_SIZE];
    int right[RIGHT_SIZE];
    int i, j, k;

    // 填上左边的数组
    for (i = L; i < M; i++) {
        left[i - L] = array[i];
    }
    // 填上右边的数组
    for (i = M; i <= R; i++) {
        right[i - M] = array[i];
    }

    // 初始化三个变量为对应数组的起始位置
    // i: 指向left数组的起始位置
    // j: 指向right数组的起始位置
    // k: 指向array数组的起始位置
    i = 0;
    j = 0;
    k = L;

    // 比较left和right数组中i和j指向的元素的大小进行归并,将元素填充到array数组中
    while (i < LEFT_SIZE && j < RIGHT_SIZE) {
        if (left[i] < right[j]) {
            array[k] = left[i];
            i++;
            k++;
        } else {
            array[k] = right[j];
            j++;
            k++;
        }
    }
    // 将left或者right数组中剩余的元素填充到array数组中
    while (i < LEFT_SIZE) {
        array[k] = left[i];
        i++;
        k++;
    }
    while (j < RIGHT_SIZE) {
        array[k] = right[j];
        j++;
        k++;
    }
}

// 实现分治,将数组不断二分的过程
void merge_sort(int array[], int L, int R) {
    // 如果这一段只有一个元素,那么它一定是有序的
    if (L == R) {
        return ;
    } else { // 否则将数组二分
        int M = (L + R) / 2;
        merge_sort(array, L, M);
        merge_sort(array, M + 1, R);
        // 这里需要注意,我们这里求出来的M和上面merge函数中传过去的M
        // 表示的位置实际上是不一样的,这里求出来的M刚好指向了左半边
        // 数组的最后一个元素,而merge函数中需要的M指向的是右半边数组
        // 的第一个元素,所以这里把M加1当作参数传给merge函数进行调用
        merge(array, L, M + 1, R);
    }
}

int main()
{
    // 定义测试数组
    int array[] = {7, 3, 4, 9, 2, 1, 0, 13};
    int L = 0;
    int R = 7;
    // 调用归并函数进行排序
    merge_sort(array, L, R);

    // 遍历展示
    int i;
    for (i = 0; i <= R; i++) {
        printf("%d\n", array[i]);
    }
    return 0;
}

运行结果:
归并排序-(C语言实现)_第1张图片

你可能感兴趣的:(数据结构及相关算法复习,c语言,算法,归并排序,分治,递归)