排序方法之归并排序(C语言实现)

小白的排序学习记录

(四)归并排序

1.思想:使用分治的思想,将要排序的数分组,分完再排,每排完两组就合并这两个数组,不断合并,合并到只有一个数组时就排好了

2.中心代码:递归+循环

3.具体实现:两个函数,一个函数分组,一个函数归并,归并的时候就相当于把两个数组排序了。

(1)实现归并的函数:将传入的两个子数组,分别拷贝到定义的左数组和右数组中,使用插入排序的方法,将两个子数组插入到大数组中,从下标1开始,依次比较两个数组中的元素,假如left[0]>right[0],将right[0]存入大数组array中,0+1,下一次就是left[1]和right[0]比较,依次循环直到某个子数组排完了,若某一个子数组还没排完,就将剩下的直接插在array的后面。
(2)实现分组的函数:找到传入数组的中间数,利用中间数将数组分成两个子数组。计算公式:mid=left+(right-left)/2;
(3)代码
1//此函数用于归并两个子数组,归并的时候就将两个子数组排好了 
void merge(int *array, int left, int mid, int right)

    
    int left_size=mid-left+1, right_size=right-mid;
//子数组分别的大小 
    int left_array[left_size], right_array[right_size];//定义左右两个数组存储传入的子数组 
    for(int i=0;i<left_size;i++)//将两个子数组拷贝到,创建的左右子数组中 
    {
        left_array[i]=array[left+i];
     } 
     for(int j=0;j<right_size;j++)
     {
         right_array[j]=array[mid+1+j];
     }
     int i=0, j=0, k=left;
//分别为左数组,右数组,大数组的循环下标 
     while(i<left_size&&j<right_size)//插入排序将两个数组插入大数组中 ,左右某一个子数组插入完了,就停止循环 
     {
         if(left_array[i]<=right_array[j])
//如果左0<右0,将左0存入大0中 
         {
             array[k]=left_array[i];
             i++;//
左++,左下一个与右0比较 
         }
         else
         {
             array[k]=right_array[j];
             j++;
         }
         k++;
     }
     while(i<left_size)//
如果左数组还有没排完的数,直接插在大数组的后面 
     {
         array[k]=left_array[i];
         i++;
         k++;
     }
     while(j<right_size)
// 如果右数组还有没排完的数,直接插在大数组的后面 
     {
         array[k]=right_array[j];
         j++;
         k++;
     }
}
2//此函数用于分子数组 

void merge_sort(int *array, int left, int right)
{
    if(left<right)//
当数组中只有一个数时不进行排序,和判断是否已经将数组分到了最小,左右重合了,重合了就不需要分了 
    {
        int mid=left+(right-left)/2;
//找中间数 
        merge_sort(array, left, mid);
        merge_sort(array, mid+1, right);//
分别分为左右两个子数组 
        merge(array, left, mid, right);//分完后将两个子数组进行归并 
    }
 } 

(4)总代码

#include<stdio.h>
#include<stdlib.h>
//此函数用于归并两个子数组,归并的时候就将两个子数组排好了 
void merge(int *array, int left, int mid, int right)

    
    int left_size=mid-left+1, right_size=right-mid;//子数组分别的大小 
    int left_array[left_size], right_array[right_size];//定义左右两个数组存储传入的子数组 
    for(int i=0;i<left_size;i++)//将两个子数组拷贝到,创建的左右子数组中 
    {
        left_array[i]=array[left+i];
     } 
     for(int j=0;j<right_size;j++)
     {
         right_array[j]=array[mid+1+j];
     }
     int i=0, j=0, k=left;//分别为左数组,右数组,大数组的循环下标 
     while(i<left_size&&j<right_size)//插入排序将两个数组插入大数组中 ,左右某一个子数组插入完了,就停止循环 
     {
         if(left_array[i]<=right_array[j])//如果左0<右0,将左0存入大0中 
         {
             array[k]=left_array[i];
             i++;//左++,左下一个与右0比较 
         }
         else
         {
             array[k]=right_array[j];
             j++;
         }
         k++;
     }
     while(i<left_size)//如果左数组还有没排完的数,直接插在大数组的后面 
     {
         array[k]=left_array[i];
         i++;
         k++;
     }
     while(j<right_size)// 如果右数组还有没排完的数,直接插在大数组的后面 
     {
         array[k]=right_array[j];
         j++;
         k++;
     }
}
//此函数用于分子数组 
void merge_sort(int *array, int left, int right)
{
    if(left<right)//当数组中只有一个数时不进行排序,和判断是否已经将数组分到了最小,左右重合了,重合了就不需要分了 
    {
        int mid=left+(right-left)/2; //找中间数 
        merge_sort(array, left, mid);
        merge_sort(array, mid+1, right);//分别分为左右两个子数组 
        merge(array, left, mid, right);//分完后将两个子数组进行归并 
    }
 } 
 int main()
 {
     int array[]={5, 1, 2, 4, 32, 1};
     int size=sizeof(array)/sizeof(array[0]);
     merge_sort(array, 0, size-1);
    for(int i=0;i<size;i++)
    {
        printf("%d ", array[i]); 
    }
     return 0;
 }

  • 36
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值