归并排序(C语言)

给定你一个长度为 n 的整数数列。

请你使用归并排序对这个数列按照从小到大进行排序。

并将排好序的数列按顺序输出。

输入格式

输入共两行,第一行包含整数 n。

第二行包含 n 个整数(所有整数均在 1∼10的9次方 范围内),表示整个数列。

输出格式

输出共一行,包含 n 个整数,表示排好序的数列。

数据范围

1≤n≤100000

输入样例:
5
3 1 2 4 5
输出样例:
1 2 3 4 5

#include<stdio.h>

int tem[100010];

int arr[100010];

//归并排序函数

void merge_sort(int arr[],int l,int r)

{

//递归的中止情况

if(l>=r) return;

1.取中间值,用来划分左右两个序列

int mid=l+r>>1;

//这种写法是位运算符中的右移运算符,表示计算机中二进制右移一位,等价于(l+r)/2;,但位运算会快一点,由于+的优先级比>>高,因此这里不用加括号

2.把原来的序列通过递归分成长度为1的子序列

merge_sort(arr,l,mid),merge_sort(arr,mid+1,r);

3.合并子序列(归并排序主要难点)

int k=0,i=l,j=mid+1;

//想要合并,就得设置一个新的数组tem用来存放合并后的数组,k为tem的角标

//双指针遍历比较:设i和j为为两个子序列的第一个元素,由于两者已经排好序,因此可以开始一个一个比较,小的放入tem数组,然后指针往后移动一位,如此循环

while(i<=mid&&j<=r)

{

if(arr[i]<=arr[j]) tem[k++]=arr[i++];

else tem[k++]=arr[j++];

}

//当一边已经进行到底时,剩下的一边直接放入给定的tem数组中(记住两边都是已经排好序的,因此全部放进去仍然有序)

while(i<=mid) tem[k++]=arr[i++];

while(j<=r) tem[k++]=arr[j++];

for(i=l,j=0;i<=r;i++,j++) arr[i]=tem[j];//把tem数组已经排好序的数放回arr中,结束;

}

int main()

{

int n;

scanf("%d",&n);

for(int i=0;i<n;i++)

{

scanf("%d",&arr[i]);

}

merge_sort(arr,0,n-1);

for(int i=0;i<n;i++)

{

printf("%d ",arr[i]);

}

return 0;

}

总结归并思路

1.有数组 arr, 左端点 l, 右端点 r

2.确定划分边界 mid

3.递归处理子问题 arr[l..mid], arr[mid+1..r]

4.合并子问题

(1)主体合并

至少有一个小数组添加到 tem 数组中

(2)收尾

可能存在的剩下的一个小数组的尾部直接添加到 tem 数组中

(3)复制回来

tmp 数组覆盖原数组

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值