暑假学习——并归排序

并归排序是属于快速排序法的一种,基本思想分为三步如下。

第一步:根据递归算法不断进行拆分,每一次都把每个子序列拆分为两个长度相等的子序列(有时候会多出一个元素来就像图中第二行
如图(这一步是到图片中第四行
请添加图片描述
第二步:当拆分到不能拆分时,进行排序,而我们通常递归到最后每个序列的元素只有一个所以并不需要排序。
第三步:每一次都将原本拆分过的两部分合并在一起,这个过程是并归排序的主要步骤,当我们合并两个有序序列的时候会进行比较如下图
请添加图片描述
这个图的意思就是b将会是一个temp空间,我们比较完成后会把较小的元素放在temp空间里。

代码展示:

#include <bits/stdc++.h>

using namespace std;

const int maxn=100000;
int a[maxn+10],temp[maxn+10];

void msort(int l,int r)/*传入左边界和右边界*/
{
    if(l>=r)
        return ;
    int mid= l+r >> 1;/*确定中点*/
    msort(l,mid);/*这两行就是在进行第一步了*/
    msort(mid+1,r);/*注意mid位置不要重复*/
    int k=0,i=l,j=mid+1;/**      *        */
    while(i<=mid&&j<=r)/*第三步*/
    {
        if(a[i]<=a[j])/*符合条件了*/
        {
            temp[k++]=a[i++];
        }
        else
        {
            temp[k++]=a[j++];/*毕竟会有一个大一个小*/
        }
    }
    while(i<=mid)/*这两个while是把所有剩下的零碎元素加到temp中*/
    {
        temp[k++]=a[i++];
    }
    while(j<=r)
     {
        temp[k++]=a[j++];
     }
     for(i=l,j=0;i<=r;i++,j++)/*把已经排序完毕的temp再复制给a*/
     {
         a[i]=temp[j];
     }
}
int main()
{
  int t;
  for(cin>>t;t;t--)
  {
      int n;
      cin>>n;
      for(int i=0;i<n;i++)
      {
          a[i]=n-i;
      }
      msort(0,n-1);
      for(int i=0;i<n;i++)
      {
          cout<<a[i]<<" ";
      }
      cout<<endl;

  }
}

下面是模板引用自CSDN博客

void merge_sort(int q[], int l, int r)
{
    if (l >= r) return;

    int mid = l + r >> 1;//确定中点
    merge_sort(q, l, mid);//递归排左边
    merge_sort(q, mid + 1, r);//递归排右边

    int k = 0, i = l, j = mid + 1;//k表示表示当前tmp中有多少个数,i和j两个指针:表示左右两边的起点
    while (i <= mid && j <= r)//小于等于左半边的边界&&小于等于右半边的边界
        if (q[i] <= q[j]) tmp[k ++ ] = q[i ++ ];//如果(q[i] <= q[j]),把q[i]拿过来放入数组
        else tmp[k ++ ] = q[j ++ ];//否则把q[j]拿过来放入数组

    while (i <= mid) tmp[k ++ ] = q[i ++ ];//如果左半边没有循环完,就把左半边的数据拿过来
    while (j <= r) tmp[k ++ ] = q[j ++ ];//如果右半边没有循环完,就把右半边的数据拿过来

    for (i = l, j = 0; i <= r; i ++, j ++ ) q[i] = tmp[j];//最后吧tmp里边的数复制回q里边
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值