论审题的重要性!!!
审题审题审题!!!!
题目描述:
根据维基百科的定义:
插入排序是迭代算法,逐一获得输入数据,逐步产生有序的输出序列。每步迭代中,算法从输入序列中取出一元素,将之插入有序序列中正确的位置。如此迭代直到全部元素有序。
归并排序进行如下迭代操作:首先将原始序列看成 N 个只包含 1 个元素的有序子序列,然后每次迭代归并两个相邻的有序子序列,直到最后只剩下 1 个有序的序列。
现给定原始序列和由某排序算法产生的中间序列,请你判断该算法究竟是哪种排序算法?
这本不是道难题,整体的解题思路很容易就想到,只需加几个标记即可,判断是哪种算法,判断已经执行了多少趟。
但,我跪的地方在归并算法的执行。
题目分析:
错误且浮躁的解法:
误以为是普通的归并排序,以为能在30分钟左右解决这道题,毕竟已经实现过归并排序的算法。太年轻了,,,哭泣
然而,当我检查好几遍算法确信算法无误后,回头审题,才意识到,我实现的是递归的归并排序,题目的意思是非递归实现。。。。。That’s the point.
手动掐死自己
AC代码:
#include<bits/stdc++.h>
using namespace std;
int init_in[100]; //用于测试插入排序
int init_me[100]; //用于测试归并排序
int ans_me[100];
int target[100];
int flag;
int cnt_m,cnt_M;
int n; //元素的个数
bool isEqual(int a[],int b[]){
for (int i = 0; i < n;i++){
if(a[i]!=b[i]){
return false;
}
}
return true;
}
void Insertion_sort(int A[],int n){
int i,p;
int cnt = 1000;
for(p=1;p<n;p++){
int tmp=A[p];
for(i=p;i>0&& tmp<A[i-1];i--){
A[i]=A[i-1];
}
A[i]=tmp;
if(isEqual(A,target)){
flag = 1; //表明是插入排序
cnt = p;
}
if(flag==1 && p==cnt+1){
return; //再排一趟
}
}
}
void Merge(int A[],int tmpA[],int L,int R,int RightEnd){
int LeftEnd = R - 1;
int tmp = L;
int count = RightEnd - L + 1;
while(L<=LeftEnd && R<=RightEnd){
if(A[L]<=A[R]){
tmpA[tmp++] = A[L++];
}
else{
tmpA[tmp++] = A[R++];
}
}
while (L<=LeftEnd){
tmpA[tmp++] = A[L++];
}
while (R<=RightEnd){
tmpA[tmp++] = A[R++];
}
for (int i = 0; i < count;i++,RightEnd--){
A[RightEnd]=tmpA[RightEnd];
}
}
void Merge_pass(int A[],int tmpA[],int n,int length){
int i;
for(i=0;i<=n-2*length;i+=2*length){
Merge(A,tmpA,i,i+length,i+2*length-1);
}
if(i+length<n){
Merge(A,tmpA,i,i+length,n-1);
}
else{
for(int j=1;j<n;j++){
tmpA[j]=A[j];
}
}
cnt_m+=1;
if(isEqual(A,target)){
flag = 2; //表明是归并排序
cnt_M = cnt_m;
// cout<<cnt_M<<" cnt_M"<<endl;
}
if(cnt_m==cnt_M+1){
for(int i=0;i<n;i++){
ans_me[i]=A[i];
}
}
}
void Merge_sort(int A[],int n){
int length=1;
int *tmpA = (int *)malloc(n*sizeof(int));
if(tmpA!=NULL){
while(length<n){
Merge_pass(A,tmpA,n,length);
length*=2;
Merge_pass(tmpA,A,n,length);
length*=2;
}
free(tmpA);
}
}
int main()
{
int num;
cin>>n;
for(int i=0;i<n;i++){
cin>>num;
init_in[i] = num;
init_me[i] = num;
}
for(int i=0;i<n;i++){
cin>>num;
target[i] = num;
}
Insertion_sort(init_in, n);
Merge_sort(init_me, n);
if(flag==1){
cout<<"Insertion Sort"<<endl;
for (int i = 0; i < n;i++){
if(i!=0){
cout<<" ";
}
cout << init_in[i];
}
}
else if(flag==2){
cout<<"Merge Sort"<<endl;
for (int i = 0; i < n;i++){
if(i!=0){
cout<<" ";
}
cout << ans_me[i];
}
}
return 0;
}