1089 Insert or Merge (插入排序,相邻归并排序,附模拟实现)

注意点1:判断插入排序不能从头开始判断是否为目标数组,

比如:初始为1 2 3 4 3,目标数组也为1 2 3 4 3,则如果是从头开始推的,则下一步会变成1 2 3 4 3,而下一步应该是 1 2 3 3 4。所以我们应该从第一个无序的位置开始排序。也就是从最后一个3开始排序判断目标数组。

注意点2:题目中的归并排序为相邻归并(递推归并),而非中分归并(递归归并)。

技巧点:排序可以用sort减少思考步骤。

常规模拟版

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
int a[110],b[110],c[110];
int n;
bool check(){
    for(int i=0;i<n;i++){
        if(c[i]!=b[i])return 0;
    }
    return 1;
}
void print(){
    for(int i=0;i<n;i++){
        cout<<c[i];
        if(i!=n-1)cout<<' ';
    }
}
bool insert(){
    bool flag=0;
    for(int i=1;i<n;i++){
        //找到第一个无序的位置排序。
        if(c[i-1]<=c[i])continue;
        if(check())flag=1;
        int pos=i;
        int temp=c[i];
        while(pos>0&&c[pos-1]>temp){
            c[pos]=c[pos-1];
            pos--;
        }
        c[pos]=temp;
        if(flag)return 1;
    }
    return 0;
}
void merge(){
    bool flag=0;
    for(int len=2;len<=n;len*=2){
        if(check())flag=1;
        for(int l=0;l<n;l+=len){
            int r=min(n-1,l+len-1);
            int mid=l+len/2-1;
            int i=l,j=mid+1;
            vector<int>temp;
            while(i<=mid&&j<=r){
                if(c[i]<=c[j])temp.push_back(c[i++]);
                else temp.push_back(c[j++]);
            }
            while(i<=mid)temp.push_back(c[i++]);
            while(j<=r)temp.push_back(c[j++]);
            for(i=l,j=0;i<=r;i++,j++){
                c[i]=temp[j];
            }
        }
        if(flag)return ;
    }
}
int main(){
    cin>>n;
    for(int i=0;i<n;i++)cin>>a[i];
    for(int i=0;i<n;i++)cin>>b[i];
    memcpy(c,a,sizeof a);
    if(insert()){
        cout<<"Insertion Sort"<<endl;
        print();
    }else {
        memcpy(c,a,sizeof a);
        merge();
        cout<<"Merge Sort"<<endl;
        print();
    }
}

sort版

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
int a[110],b[110],c[110];
int n;
bool check(){
    for(int i=0;i<n;i++){
        if(c[i]!=b[i])return 0;
    }
    return 1;
}
void print(){
    for(int i=0;i<n;i++){
        cout<<c[i];
        if(i!=n-1)cout<<' ';
    }
}
bool insert(){
    bool flag=0;
    for(int i=1;i<n;i++){
        //找到第一个无序的位置排序。
        if(c[i-1]<=c[i])continue;
        if(check())flag=1;
        sort(c,c+i+1);
        if(flag)return 1;
    }
    return 0;
}
void merge(){
    bool flag=0;
    for(int len=2;len<=n;len*=2){
        if(check())flag=1;
        for(int i=0;i<n;i+=len){
            int j=min(n,i+len);
            sort(c+i,c+j);
        }
        if(flag)return ;
    }
}
int main(){
    cin>>n;
    for(int i=0;i<n;i++)cin>>a[i];
    for(int i=0;i<n;i++)cin>>b[i];
    memcpy(c,a,sizeof a);
    if(insert()){
        cout<<"Insertion Sort"<<endl;
        print();
    }else {
        memcpy(c,a,sizeof a);
        merge();
        cout<<"Merge Sort"<<endl;
        print();
    }
}
相关推荐
搞笑症患者14 分钟前
压缩感知(Compressed Sensing, CS)
算法·最小二乘法·压缩感知·正交匹配追踪omp·迭代阈值it算法
im_AMBER18 分钟前
Leetcode 101 对链表进行插入排序
数据结构·笔记·学习·算法·leetcode·排序算法
予枫的编程笔记18 分钟前
【Java集合】深入浅出 Java HashMap:从链表到红黑树的“进化”之路
java·开发语言·数据结构·人工智能·链表·哈希算法
快手技术35 分钟前
AAAI 2026|全面发力!快手斩获 3 篇 Oral,12 篇论文入选!
前端·后端·算法
颜酱37 分钟前
前端算法必备:滑动窗口从入门到很熟练(最长/最短/计数三大类型)
前端·后端·算法
做科研的周师兄39 分钟前
【MATLAB 实战】栅格数据 K-Means 聚类(分块处理版)—— 解决大数据内存溢出、运行卡顿问题
人工智能·算法·机器学习·matlab·kmeans·聚类
X在敲AI代码40 分钟前
leetcodeD3
数据结构·算法
余瑜鱼鱼鱼1 小时前
Java数据结构:从入门到精通(十一)
数据结构
码农小韩1 小时前
基于Linux的C++学习——循环
linux·c语言·开发语言·c++·算法
CoderCodingNo1 小时前
【GESP】C++五级/四级练习(双指针/数学) luogu-P1147 连续自然数和
开发语言·c++·算法