1035 插入与归并

2024-03-09 06:20
文章标签 归并 插入 1035

本文主要是介绍1035 插入与归并,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

根据维基百科的定义:

插入排序是迭代算法,逐一获得输入数据,逐步产生有序的输出序列。每步迭代中,算法从输入序列中取出一元素,将之插入有序序列中正确的位置。如此迭代直到全部元素有序。

归并排序进行如下迭代操作:首先将原始序列看成 N 个只包含 1 个元素的有序子序列,然后每次迭代归并两个相邻的有序子序列,直到最后只剩下 1 个有序的序列。

现给定原始序列和由某排序算法产生的中间序列,请你判断该算法究竟是哪种排序算法?

输入格式:

输入在第一行给出正整数 N (≤100);随后一行给出原始序列的 N 个整数;最后一行给出由某排序算法产生的中间序列。这里假设排序的目标序列是升序。数字间以空格分隔。

输出格式:

首先在第 1 行中输出Insertion Sort表示插入排序、或Merge Sort表示归并排序;然后在第 2 行中输出用该排序算法再迭代一轮的结果序列。题目保证每组测试的结果是唯一的。数字间以空格分隔,且行首尾不得有多余空格。

输入样例 1:

10
3 1 2 8 7 5 9 4 6 0
1 2 3 7 8 5 9 4 6 0

输出样例 1:

Insertion Sort
1 2 3 5 7 8 9 4 6 0

输入样例 2:

Merge Sort
1 2 3 8 4 5 7 9 0 6

/*
这里两个算法学的不好,今天学习一下算法再来看
然后这里行末不输出空格,所以这里选择数组进行输入数据;这里相当于第一行数据是原始数据
第二行是排序过程的数据,属于中间状态;
我们可以用另外一个数组存放一组数据,直接对其进行排序;插入排序未排序的与原始数据
后段一致,可以进行比较判断插入排序;现在要考虑怎么比较中间序列和原始序列;
这里N最大值为100,插入排序最坏的情况是逆序排放,就是降序排列的,每一个都要移动,
时间复杂度为O(n*n);那么中间状态最坏的情况有100*100==10000种情况;
插入排序的前端有序,后端为原始序列;所以对于插入排序是比较好判别的,那么又因为测试序列
属于的排序算法唯一,所以不是插入排序的情况下就只能是归并排序;
然后还要输出算法的下一步,所以这里要实现两个算法;这里要考虑归并的分组,就是怎么分组,怎么看出来时几个一组,这里计算机只能通过比较才能看
出来,不像人能够直观的看出来,这里我们分组只要让下标一致就可以了,
比如下标012345
0/2==0,1/2==0;
2/2==1,3/2==1;
4/2==2,5/2==2;
这里可以通过将下标除以基数得到对应的段数;然后对基数取余就得到段内的下标;
跟段地址还有点相通呢;这里归并的段内排序我就直接用qsort了,方便一点;
用sort了,qsort不知道哪里出了点问题;
*/
#include<iostream>
#include<cstdlib>
#include <algorithm>        //sort在算法头文件里;
using namespace std;
//以插入排序为基准判断排序方式;
int check(int* data,int* mid,int length){//这里注意传入三个参数,一个是原始序列,一个是中间序列,一个是长度,根据原始求下一步;//检查后端;这里前端是已经排序的,不方便比较,直接从后端没操作的数据比较;int index=0;    //标志不匹配位置的下标;for(int i=length-1;i>=0;i--){    //这里插入排序后端数据未使用原始与中间序列一致;if(data[i]!=mid[i]){index=i;break;}}//检查前端是否是有序序列;for(int i=0;i<index-1;i++){if(mid[i]>mid[i+1]){return -1;        //这里返回就是归并排序;}}return 1;    //这里返回就是插入排序;
}
//输出数组;
void out(int* a,int length){for(int i=0;i<length-1;i++){cout<<a[i]<<' ';}cout<<a[length-1]<<endl;
}
//归并排序子函数;
void merge(int* data,int N,int seg){    //seg表示归并段长度;for(int i=0;i<N;i+=seg){if(i+seg<=N){sort(data+i,data+i+seg);}else{sort(data+i,data+N);}}
}
//比较函数;判断两个数列是否等价;
bool myequal(int* a,int* b,int length){for(int i=0;i<length;i++){if(a[i]!=b[i]){return false;}}return true;
}
//归并排序函数;
void mergeSort(int* data,int* mid,int N){    //segment是排序段长;//这里归并选择用两个长度的段进行排序;//这里并不需要按找归并的方式合并相邻的两个数列;//只需要让两个数列合并成一个有序数列就好了;int count=1;    //归并段数的长度;for(count=2;count<=N;count*=2){if(myequal(data,mid,N)){    //如果相等只需要在归并一次即可退出;merge(mid,N,count);break;}else {        //不相等继续归并;第一次一定不等;merge(data,N,count);}}
}
//插入排序函数;
void insertSort(int* data,int* mid,int N){int index=0;    //标记不匹配的下标位置;int temp;        //存放即将操作的元素;//找后端下标;for(int i=N-1;i>=0;i--){    //这里插入排序后端数据未使用原始与中间序列一致;if(data[i]!=mid[i]){index=i;break;}}//进行一次插入排序;temp=mid[index+1];for(int i=index;i<N&&i>=0;i--){if(temp<mid[i]){mid[i+1]=mid[i];}else if(temp>=mid[i]){mid[i+1]=temp;break;}}
}
int main(){//输入数据;int N;cin>>N;//输入原始序列;int data[N];for(int i=0;i<N;i++){cin>>data[i];}//输入中间序列;int mid[N];for(int i=0;i<N;i++){cin>>mid[i];}//尝试判断排序类型;char type='I';    //‘I’表示插入排序,'M'表示归并排序;if(check(data,mid,N)==1){    cout<<"Insertion Sort"<<endl;type='I';}else if(check(data,mid,N)==-1){cout<<"Merge Sort"<<endl;type='M';}//指向排序的下一步;if(type=='I'){        //插入排序;insertSort(data,mid,N);out(mid,N);}else if(type=='M'){    //归并排序;mergeSort(data,mid,N);out(mid,N);}return 0;
}
/*
反思:这里不要陷入这个牛角尖,多用其他方法,都可以,然后就是排序算法的熟悉,还需要再进步
这道题还没有完全写完;部分正确;
*/

这篇关于1035 插入与归并的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/789769

相关文章

顺序表之创建,判满,插入,输出

文章目录 🍊自我介绍🍊创建一个空的顺序表,为结构体在堆区分配空间🍊插入数据🍊输出数据🍊判断顺序表是否满了,满了返回值1,否则返回0🍊main函数 你的点赞评论就是对博主最大的鼓励 当然喜欢的小伙伴可以:点赞+关注+评论+收藏(一键四连)哦~ 🍊自我介绍   Hello,大家好,我是小珑也要变强(也是小珑),我是易编程·终身成长社群的一名“创始团队·嘉宾”

matplotlib绘图中插入图片

在使用matplotlib下的pyplot绘图时,有时处于各种原因,需要采用类似贴图的方式,插入外部的图片,例如添加自己的logo,或者其他的图形水印等。 一开始,查找到的资料都是使用imshow,但是这会有带来几个问题,一个是图形的原点发生了变化,另外一个问题就是图形比例也产生了变化,当然最大的问题是图形占据了整个绘图区域,完全喧宾夺主了,与我们设想的只在绘图区域中占据很小的一块不相符。 经

【数据结构入门】排序算法之交换排序与归并排序

前言         在前一篇博客,我们学习了排序算法中的插入排序和选择排序,接下来我们将继续探索交换排序与归并排序,这两个排序都是重头戏,让我们接着往下看。  一、交换排序 1.1 冒泡排序 冒泡排序是一种简单的排序算法。 1.1.1 基本思想 它的基本思想是通过相邻元素的比较和交换,让较大的元素逐渐向右移动,从而将最大的元素移动到最右边。 动画演示: 1.1.2 具体步

MongoDB学习—(4)文档的插入,删除与更新

一,文档的插入 插入命令有两个一个为insert,另一个为save,两者的区别为 db.[documentName].insert({..})插入的数据不允许重复,即_id不可相同 db.[docuemntName].save({..})插入的数据允许重复,如果整条数据内容相同,则不发生替换,如果数据有做不同,则将原数据替换 二,删除文档数据 db.[docuementName].r

归并排序/计数排序

1:归并排序 1.1:代码 void _MergeSort(int* arr, int left, int right, int* tmp){if (left >= right){return;}int mid = (left + right) / 2; _MergeSort(arr, left, mid, tmp); _MergeSort(arr, mid+1, righ

240907-Gradio插入Mermaid流程图并自适应浏览器高度

A. 最终效果 B. 示例代码 import gradio as grmermaid_code = """<iframe srcdoc='<!DOCTYPE html><html><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width" /><title>My static Spa

java的Timestamp时间插入mysql的datetime字段是0000-00-00 00:00:00

Mysql 与 java 的时间类型             MySql的时间类型有              Java 中与之对应的时间类型                  date                                               java.sql.Date               Datetime

Hibernate插入数据时,报错:org.springframework.dao.DataIntegrityViolationException: could not insert: [cn.itc

在用junit测试:插入数据时,报一下错误: 错误原因: package junit;import org.junit.Test;import cn.itcast.crm.container.ServiceProvinder;import cn.itcast.crm.dao.ISysUserDao;import cn.itcast.crm.domain.SysRole;

【SGU】180. Inversions(归并排序求逆序数)

以前一般用树状数组和线段树做这种题 这次换个思路试试,归并排序! #include<cstdio>#include<cstring>#include<algorithm>using namespace std;typedef long long LL;const int maxn = 111111;int n;int array[maxn];int tmp[maxn];L

二分插入

思想:对于已排好序的数组,例如升序数组插入一个数字,把数组的上、下界下标做形参,方便递归,每次取中间的数与插入数进行比较,      特别注意当插入数小于中间数这种情况,这种情况下,移动时下标应从中间值那个下标开始移起(就因为这儿我Wrong了好多次) 解题代码: #include <stdio.h> #define N 100000 void Input(int a[