排序算法-归并排序(MergeSort)-C

本文介绍了使用分治思想的归并排序算法,通过递归拆分数组,合并有序子数组,避免了大量临时数组的创建。时间复杂度上,平均、最好和最坏情况都是O(n log n)。通过实例代码演示了如何在C语言中实现该算法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

思路:

使用分治思想,将问题分成一些小问题然后递归求解,再将各个小问题的解归并到一起。

使用递归,将一个数组不断分为两个更小的子数组,递归对更小的子数组排序。然后将已排序的两个子数组合并到一个新数组(这里需要额外使用一个同样大小的新数组),再将排序好的新数组中的元素拷贝回原数组。

基本操作是合并两个已经排序的数组,使用三个计数器Apos,Bpos,Cpos 初始值分别位三个数组的A,B,C的开始位置,比较A[Apos]和B[Bpos]的大小,并将较小者输出到C[Cpos ],然后计数器增加。当两个数组A和B有一个为空,则将另一个数组剩余部分拷贝到C中。

如果在merge方法中声明一个临时数组,由于merge会被递归调用很多次,在递归期间就会生成很多临时数组,占用一部分内存;另一个方面,在声明数组的过程中调用malloc 和free 分配并释放内存,也会占用一些时间。所以这里在排序算法的驱动程序中就申请一个同样大小的临时数组,在后面递归调用merge方法中共享使用。

时间复杂度:

平均:O(n\log n)  ,最好:O(n\log n) ,最坏:O(n\log n)

程序:

void merge(int array[],int tmp_array[],int left,int center,int right)
{
    int i,left_pos,right_pos,tmp_pos,length;
    length=right-left+1;
    left_pos=left;
    right_pos=center+1;
    tmp_pos=left;
    while(left_pos<=center&&right_pos<=right)          //将两个数组中的较小者输出到第三个数组
        if(array[left_pos]<array[right_pos])
            tmp_array[tmp_pos++]=array[left_pos++];
        else
            tmp_array[tmp_pos++]=array[right_pos++];

    while(left_pos<=center)                            //将第一个数组中剩余元素拷贝到第三个数组
        tmp_array[tmp_pos++]=array[left_pos++];
    while(right_pos<=right)
        tmp_array[tmp_pos++]=array[right_pos++];       //将第二个数组中剩余元素拷贝到第三个数组 

    for(i=0;i<length;i++)                              //将第三个数组中的元素拷贝回原数组中
        array[left+i]=tmp_array[left+i];
}

void merge_sort_recurise(int array[],int tmp_array[],int left,int right)
{
    int center;
    if(left<right)
    {
        center=(left+right)/2;
        merge_sort_recurise(array,tmp_array,left,center);
        merge_sort_recurise(array,tmp_array,center+1,right);
        merge(array,tmp_array,left,center,right);
    }
}

void merge_sort(int array[],int array_size)
{
    int *tmp_array=calloc(array_size,sizeof(int));
    if(tmp_array==NULL)
    {
        printf("No full space for array!\n");
        return;
    }
    merge_sort_recurise(array,tmp_array,0,array_size-1);
    free(tmp_array);
}
#include <stdio.h>
#include <stdlib.h>

int main()
{
    int i;  
    int array[]={100,96,88,75,63,52,41,36,28,19,6,0,-19,-105};
    int array_size=sizeof(array)/sizeof(int);
    printf("Original array:\n");
    for(i=0;i<array_size;i++)
        printf(" %d, ",array[i]);
    printf("\n");
    merge_sort(array,array_size);
    printf("Sorted array:\n");
    for(i=0;i<array_size;i++)
        printf(" %d, ",array[i]);
    printf("\n");
    return 0;
}

参考:

https://www.cnblogs.com/onepixel/p/7674659.html

https://www.runoob.com/w3cnote/merge-sort.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值