问题标题: 酷町堂:开学前的小王课堂~~~

1
1
已解决
王子健
王子健
初级天翼
初级天翼

上节课我们讲到了排序中的一种:选择排序

选择排序需要双重循环,时间复杂度很高,算是一种比较缓慢的排序,今天我们要讲的是很快的一种排序方式:归并排序

归并排序(MERGE-SORT)是利用归并的思想实现的排序方法,该算法采用经典的分治(divide-and-conquer)策略(分治法将问题(divide)成一些小的问题然后递归求解,而治(conquer)的阶段则将分的阶段得到的各答案"修补"在一起,即分而治之)。

分而治之

归并排序时间复杂度只有O(n log n),很快的一种算法,跟快排的系统时间复杂度是一样的,但快排和堆排序都不是很稳定:

/*

归并排序是稳定的
快速排序和堆排序都不稳定
不稳定:就是大小相同的两个数,经过排序后,最终位置与初始位置交换了。
快速排序:
27 23 27 3
以第一个27作为pivot中心点,则27与后面那个3交换,形成
3 23 27 27,排序经过一次结束,但最后那个27在排序之初先于初始位置3那个27,所以不稳定。
堆排序:
比如:3 27 36 27,
如果堆顶3先输出,则,第三层的27(最后一个27)跑到堆顶,然后堆稳定,继续输出堆顶,是刚才那个27,这样说明后面的27先于第二个位置的27输出,不稳定。”
2 归并排序(MergeSort)
归并排序先分解要排序的序列,从1分成2,2分成4,依次分解,当分解到只有1个一组的时候,就可以排序这些分组,然后依次合并回原来的序列中,这样就可以排序所有数据。合并排序比堆排序稍微快一点,但是需要比堆排序多一倍的内存空间,因为它需要一个额外的数组。

(摘自百度~)

*/

所以学习归并排序是一个很好的排序方法,但是代码实现比较长,况且C++没有帮你弄好直接用的函数,所以要自己模拟规则排序

 

下面讲解酷町堂网站4518 合并有序数组题目

思路:

1、将两个已经有序数组合并成一个,拿两个数组的第一个数字进行比较,小的数字放入新数组,一直重复
2、直到有一个数组为空,将另一个数组剩下的数字接到后面。

代码实现(模板):

#include <iostream>
using namespace std;
int a[1005], b[1005], c[2005], m, n; 
int main() {
    cin >> m >> n;
    for(int i=1; i<=m; i++) {
        cin >> a[i];
    } 
    for(int i=1; i<=n; i++) {
        cin >> b[i];
    } 
    int i = 1, j = 1, k = 0;
    while(i<=m && j<=n) {
        if(a[i] < b[j]) {
            c[++k] = a[i];
            i ++;
        }else {
            c[++k] = b[j];
            j ++;
        }
    }
    while(i<=m) {
        c[++k] = a[i];
        i ++;
    }
    while(j<=n) {
        c[++k] = b[j];
        j ++;
    }
    for(int i=1; i<=k; i++) {
        cout << c[i] << ' ';
    }
    return 0;
}
//一定要看懂再复制,不然会被处罚的!~

代码很长,需要一步一步归纳。

 

今天作业:

一道难题1445 瑞士轮,很难很难,做出来要发截图,不允许更改审查元素,需要发两张图片,一张是提交记录,一张是提交结果的全张图片,因为题目很难,此题有50个豆子!!如果一个礼拜后没有正解加至100豆!!!

此作业提交记录在春季或者冬季的不算数,因为是老师带着写的!!!

王子健在2020-08-27 20:47:54追加了内容

@陈曦    是这样的提交结果:


0
已采纳
黄子扬
黄子扬
初级天翼
初级天翼

个人的亿点点小小建议:

    1.百度尽量尽量别用,毕竟是“课堂”,不是“师生共学”

    2.主题不突出??归并排序代码呢?4518 合并有序数组题目 这只能算模拟题吧

    3.细节勘误(当然,可无视)

    

归并排序时间复杂度只有O(n log n)
归并排序平均时间复杂度只有O(n log n)

 

0
0
0
刘宇唐
刘宇唐
中级守护
中级守护

老是说我没有源文件地址

0
刘宇唐
刘宇唐
中级守护
中级守护

直接给你代码吧

别举报

之前在oj上做过的

#include<iostream> 
#include<algorithm>    
using namespace std;  
int n,r,q;  
int a[200100],win[200100],lose[200100];  
int s[200100],w[200100];   
bool cmp(int x,int y)  
{  
    if(s[x]==s[y])   return x<y;
    return s[x]>s[y];
}  
void merge()
{  
    int i,j;  
    i=j=1,a[0]=0;  
    while(i<=win[0] && j<=lose[0])  
    if(cmp(win[i],lose[j]))  
        a[++a[0]]=win[i++];  
    else   
        a[++a[0]]=lose[j++];  
    while(i<=win[0])a[++a[0]]=win[i++];  
    while(j<=lose[0])a[++a[0]]=lose[j++];          
}  
int main()  
{  
    cin>>n>>r>>q;n*=2;  
    for(int i=1;i<=n;i++)a[i]=i;  
    for(int i=1;i<=n;i++)cin>>s[i];  
    for(int i=1;i<=n;i++)cin>>w[i];  
    sort(a+1,a+n+1,cmp);  
    for(int i=1;i<=r;i++)  
    {  
        win[0]=lose[0]=0;  
        for(int j=1;j<=n;j+=2)  
            if(w[a[j]]>w[a[j+1]])
            {  
                s[a[j]]++;  
                win[++win[0]]=a[j];  
                lose[++lose[0]]=a[j+1];  
            }  
            else
            {  
                s[a[j+1]]++;  
                win[++win[0]]=a[j+1];  
                lose[++lose[0]]=a[j];  
            }    
        merge();          
    }  
    cout<<a[q];
    return 0;  
}

 

0
陈曦
陈曦
资深天翼
资深天翼

“一张是提交结果的全张图片”

这个最好撤回,

不然就成了发整段代码

0
0
刘宇唐
刘宇唐
中级守护
中级守护

楼主你直接查我提交记录吧

0
0
0
0
李致远
李致远
高级光能
高级光能

不错是不错,但是建议可以讲得详细一点,比如我这个蒟蒻就没听懂。。。

建议:

1 代码实现归并排序(加注释)

2 讲解归并排序的详细步骤

0
丁博扬
丁博扬
中级天翼
中级天翼

不错

科室我才学到函数,怎么说呢,我不会,看不懂

【滑稽】【滑稽】

丁博扬在2020-08-28 08:12:15追加了内容

可是,不是科室

丁博扬在2020-08-28 08:12:20追加了内容

可是,不是科室

0
赵逸凡
赵逸凡
初级启示者
初级启示者

今天的作业是你的每日一题吧

还有,那个要求发整段代码有点。。。

顺便,你挺爱加别人QQ啊

我要回答