PAT 1089 Insert or Merge C++版

版权声明:如若转载,请联系作者。 https://blog.csdn.net/liu16659/article/details/89526179

PAT 1089 Insert or Merge C++版

1.题意

题意很简单,就是给出一个源数组,然后再给出一个中间数组,让你判断这个中间数组是通过“插入排序”,还是“归并排序”得到?

2.分析

对于这题,主要思路如下:

  • step 1:首先判断是由哪种方法得到这个序列
  • step 2:如果是插入排序,那么再进行下一步插入,然后输出
  • step 3:如果是归并排序,那么还需要多知道一点儿事情,就是下一步该进行几项归并?

具体实现方法:

  • step 1:针对排序的规律,我们知道,如果是插入排序,那么前k个数字肯定是有序的,后n-k个数字跟源数组肯定是一模一样的,针对这个特点,我们得到函数isInsert()。用于判断是否是插入排序,如果不是则是归并排序。
  • step 2: 插入排序的实现很简单,这里我不再啰嗦。
  • step 3:先找到归并排序的项数,这个稍有难点,但其实仔细想一下,也就不难,我们要找的是,这个中间序列中的归并项数max,然后将这个max*2就得到了下次我们要归并的项数了。但是如何找到中间序列的归并项数呢?方法如下:
    我们遍历中间序列,找出其中最小的连续上升序列项就可以了。通过一个for循环和一个值比较过程就可以实现。

3.代码

#include<cstdio>
#include<iostream>
#include<algorithm> 
#define maxn 105
using namespace std;

int N;
int ori[maxn];//原始数组 
int part[maxn];//中间数组
int maxOrder;//记录最大的顺序数

int isInser(){	
	int i,j;
	for(i = 1;i < N;i++){ //注意这里的i起始值为 1 
		if(part[i] < part[i-1]){//i 是非顺序序列的最后一位 			
			maxOrder = i;
			break;//跳出循环 
		}
	}
	for(j = maxOrder;j < N;j++){
		if(ori[j] != part[j]){
			return -1;//返回 -1 		
		}
	}
	return maxOrder;//返回下标值 
	
}

//进行一次插入排序 
void insertSort(){
	int ele = ori[maxOrder];//待插入的数 
	int i,j;
	for(i = 0; i < N; i++) {//进行插入排序 
		if(ele < part[i]){//如果待插入的元素小于 part[i],则需要开始进行移位 
			for(j = maxOrder; j > i; j--){
				part[j] = part[j-1];
			} 
			part[i] = ele;
			break; 
		} 
	}	
} 

//找出合并排序中最大的有序数值n 
int getN(){
	int count = 1;
	int max = N;//将N个作为归并项 
	int i ,j;
	for(i = 1;i< N;i++){
		if(part[i] >= part[i-1]){//如果连续单调递增 
			count ++; 
		}
		else{
			if(count < max){
				max = count;//重置max的值 
			}
			count = 1;//重置为1 
		}
	}
	return max;//返回上次归并的项数
}

//进行一次合并排序 ,k个数一起合并 
void megerSort(int k){
	int ele = ori[maxOrder];//待插入的数 
	int i,j;
	for(i = 0; i < N; i+=k) {//进行插入排序 
		if(i+k >= N){//如果越界 
			sort(part+i,part+N); 
		}
		else sort(part+i,part+i+k);//进行一次排序		
	}	
}

void print(){
	for(int i = 0; i < N; i++) {//输出
		if(i!=N-1)	cout << part[i] << " ";	
		else cout << part[i];
	} 	
} 

int main(){	
	cin >> N;
	int i;	
	for(i = 0;i < N;i++){
		cin >> ori[i] ;
	}	
	
	for(i = 0;i< N;i++){
		cin >> part[i];
	} 
	
	if(isInser() != -1){//如果是插入排序 
		insertSort();//进行一次插入排序,并输出结果 
		cout << "Insertion Sort\n";
		print();
	}
	else{
		//cout << getN() <<"++\n";//
		cout << "Merge Sort\n";
		megerSort(2*getN());
		print(); 
	} 
}

4.测试用例

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


4
3 4 2 1
3 4 2 1

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


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


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

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

5.执行结果

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/liu16659/article/details/89526179