十大排序算法——归并排序(C语言)

归并排序

归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。归并排序是一种稳定的排序方法。
该算法采用经典的分治(divide-and-conquer)策略(分治法将问题分(divide)成一些小的问题然后递归求解,而治(conquer)的阶段则将分的阶段得到的各答案"修补"在一起,即分而治之)。

基本思想

先递归分组再合并相邻的两个组
1.将一个待排序序列进行分组,分为左子数组和右子数组,对左右子数组进行排序形成有序的子数组,在进行合并成一个完整的有序序列。
2.对左右子数组进行排序使用递归的方式进行,就是对左右子数组继续进行分组,直到每个组中只有一个元素,说明分组完成,组中的元素已经达到有序,然后在合并相邻的两个组。
3.合并方式为:首先创建一个和原数组相同的数组用来存放合并后的数组,然后比较左右子数组的第一个元素,谁小就把谁放在新数组的0索引处。(如果左子数组的第一个数比右子数组的第一个数小就把左子数组第一个数放在新数组的0索引处,在把左子数组+1继续和右子数组的第一个数进行比较,谁小就把谁放在新数组的1索引处,如果右子数组的第一个数小,就右子数组+1继续和左子数组+1进行比较,谁小就把谁放在新数组的2索引处,依次进行比较,直到合并成一个组,就把新数组里的元素都赋值给原数组)
分解合并的过程图解
分治

归并排序代码(C语言)

#include <stdio.h>
#include <stdlib.h>

//归并排序
//将两个有序子数组合并操作
void Sort(int a[],int temp[],int left,int mid,int right)
{
    int i,j,t;
    i = left;  //左序列指针
    j = mid+1;  //右序列指针
    t = 0;  //临时数组指针
    while (i <= mid && j <= right)
    {
        if (a[i] < a[j])
        {
            temp[t++] = a[i++];
        }
        else
        {
            temp[t++] = a[j++]; 
        }
        
        
    }
    while (i<=mid)  //将左边剩余元素填充进temp中
    {
        temp[t++] = a[i++];
    }
    while (j<=right)   // 将右序列剩余元浸塑填充进temp中
    {
        temp[t++] = a[j++];
    }
    t=0;
    //将temp中的元素全部拷贝到原数组中
    while (left <= right)
    {
        a[left++] = temp[t++];
    }

}
//使用递归分组进行
void Merge_Sort(int a[],int temp[],int left,int right)
{
    if (left<right)
    {
        int mid = (left+right)/2;
        Merge_Sort(a,temp,left,mid);  // 左边归并排序,使得左子序列有序
        Merge_Sort(a,temp,mid+1,right);  //右边归并排序,使得右子序列有序
        Sort(a,temp,left,mid,right);  //将两个有序子数组合并操作
    }
    
}
void main()
{
    int a[]={16,36,69,56,65,45,52,36,96,2};
    int n=sizeof(a)/sizeof(int);    //计算数组元素
    int i,b[n]; 
    Merge_Sort(a,b,0,n);
    for ( i = 0; i < n; i++)
    {
        printf("%d ",a[i]);
    }
    system("pause");   //防止控制台闪退

}

参考文献
图解排序算法(四)之归并排序

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

西瓜籽@

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值