排序方法之归并

排序方法之归并

本期课程,小编将手把手教诲大家归并排序。
这里写图片描述
一、 排序的分类及优缺点:
1、 选择排序:简单排序,时间复杂度高,空间复杂度低,不稳定;
2、 插入排序:简单排序,时间复杂度高,空间复杂度低,稳定;
3、 冒泡排序:简单排序,时间复杂度高,空间复杂度低,稳定;
4、 桶排序:时间复杂度中,空间复杂度高,稳定;
5、 归并排序:时间复杂度中,空间复杂度高,稳定;
6、 快速排序:时间复杂度低,空间复杂度中,不稳定;

二、 归并排序:
归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。归并过程为:比较a[i]和b[j]的大小,若a[i]≤b[j],则将第一个有序表中的元素a[i]复制到r[k]中,并令i和k分别加上1;否则将第二个有序表中的元素b[j]复制到r[k]中,并令j和k分别加上1,如此循环下去,直到其中一个有序表取完,然后再将另一个有序表中剩余的元素复制到r中从下标k到下标t的单元。归并排序的算法我们通常用递归实现,先把待排序区间[s,t]以中点二分,接着把左边子区间排序,再把右边子区间排序,最后把左区间和右区间用一次归并操作合并成有序的区间[s,t]。

我们先来看二路归并的代码:

#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
int a[10001],r[10001];
void merge(int s,int y,int t);
int main()
{
    int n,m;
    cin>>m>>n;
    for (int i=1;i<=n;++i)
        scanf("%d",&a[i]);      //up
    merge(1,m,n);
    for (int i=1;i<=n;++i)
        printf("%d ",r[i]);
    return 0;
}
void merge(int s,int y,int t)
{
    int i=s,j=y+1,p=s;
    while(i<=y&&j<=t)
        if (a[i]<=a[j]) {r[p]=a[i];++p;++i;}
        else {r[p]=a[j];++p;++j;}
    while (i<=y) {r[p]=a[i];++i;++p;}
    while (j<=t) {r[p]=a[j];++j;++p;}
}

下面我们再来讨论分治法的归并排序:

伪代码算法流程如下:
1、原始数据输入;
2、mergesort(1,n);
3、数据输出;
这里的2需要细化。
代码如下:

#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
int a[10001],r[10001];
void merge(int s,int y,int t);
void mergesort(int s,int t);
int main()
{
    int n;
    cin>>n;
    for (int i=1;i<=n;++i)
        scanf("%d",&a[i]);      //up
    mergesort(1,n);
    for (int i=1;i<=n;++i)
        printf("%d ",a[i]);
    return 0;
}
void merge(int s,int y,int t)
{
    int i=s,j=y+1,p=s;
    while(i<=y&&j<=t)
        if (a[i]<=a[j]) {r[p]=a[i];++p;++i;}
        else {r[p]=a[j];++p;++j;}
    while (i<=y) {r[p]=a[i];++i;++p;}
    while (j<=t) {r[p]=a[j];++j;++p;}
    for (int i=s;i<=t;++i)
        a[i]=r[i];
}
void mergesort(int s,int t)
{
    int m;
    if (s==t) return ;
    m=(s+t)/2;
    mergesort(s,m);
    mergesort(m+1,t);
    merge(s,m,t);
}

三、 sort()函数的使用:
sort()函数是c++一种排序方法之一,因为它使用的排序方法是类似于快排的方法,时间复杂度为n*log2(n),执行效率较高!
c++标准库里的排序函数的使用方法:
1、Sort函数包含在头文件为#include的c++标准库中,调用标准库里的排序方法可以不必知道其内部是如何实现的,只要出现我们想要的结果即可!
2、Sort函数有三个参数:
(1)第一个是要排序的数组的起始地址。
(2)第二个是结束的地址(最后一位要排序的地址)
(3)第三个参数是排序的方法,可以是从大到小也可是从小到大,还可以不写第三个参数,此时默认的排序方法是从小到大排序。
Sort函数使用模板:
Sort(arr+start,arr+end+1,排序方法);
代码如下:

#include<iostream>
#include<algorithm>
#include<string>
using namespace std;
string st[1001];
int main()
{
    int n;
    cin>>n;
    for (int i=1;i<=n;++i)
        cin>>st[i];
    sort(st+1,st+n+1);
    for (int i=1;i<=n;++i)
        cout<<st[i]<<endl;
    return 0;
}

#include<iostream>
#include<algorithm>
#include<string>
using namespace std;
int a[1001];
bool comp(int a,int b)
{
    return a>b;
}
int main()
{
    int n;
    cin>>n;
    for (int i=1;i<=n;++i)
        cin>>a[i];
    sort(a+1,a+n+1,comp);     //注意,这里不需要传入参数; 
    for (int i=1;i<=n;++i)
        cout<<a[i]<<' ';
    return 0;
}

好啦,本期的课程就到此为止了,如果喜欢小编的博客,就赶紧订阅吧。小编会不定期的更新文章,感谢大家的支持,我们下期再见!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值