1089 Insert or Merge (25分)/归并排序模拟

归并排序有递归写法和非递归写法,但是由于栈内存的开销以及时间的消耗,往往使用非递归的算法。归并排序顾明思议是将几个有序的序列归并到一个序列,使用的merge函数是采用two pointer的方法。
题目中如果要模拟归并排序,自己去写merge函数就太耗时了,如果只是要模拟过程,可以用STL 中的sort函数替换merge(当然,时间消耗会多一点)。

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int main() {
	//freopen("1.txt", "r", stdin);
	int n; cin >> n;
	vector<int> a(n);
	for (int i = 0; i < n; i++) {
		cin >> a[i];
	}
    //由于最后一段可能不能不够step,所以条件判断是step/2<n而不是step<n
	//条件判断中取不取等都可以
	for (int step = 2; step / 2 < n; step *= 2) { 
		for (int i = 0; i < n; i += step)
			sort(a.begin() + i, a.begin() + min(i + step, n));  //借用快排
		   //min(i+step,n)用于最后一段,不过最后一段也可以单独求
	}
	for (int i = 0; i < n; i++) {
		cout << a[i];
		if (i != n - 1) cout << " ";
	}
	return 0;
}

1089 Insert or Merge (25分)

题目大意

现给定原始序列和由某排序算法产生的中间序列,请你判断该算法是插入算法还是归并算法。首先在第1行中输出“Insertion Sort”表示插入排序、或“Merge Sort”表示归并排序;然后在第2行中输出用该排序算法再迭代一轮的结果序列

分析

根据插入排序和归并排序的特点,插入排序前一部分有序,后一部分和原序列相同。一旦排除插入排序,则是归并排序,对原始序列模拟归并排序,当和中间序列相同时再进行一次归并几位所求结果。
注意:序列中可能存在相等的数。

AC代码

#include<iostream>
#include<algorithm>
using namespace std;
int main() {
	//freopen("1.txt", "r", stdin);
	int n; cin >> n;
	int *a = new int[n];
	int *b = new int[n];
	for (int i = 0; i < n; i++) {
		cin >> a[i];
	}
	for (int i = 0; i < n; i++) {
		cin >> b[i];
	}
	int k, j;
	for (k = 0; k < n - 1 && b[k] <= b[k + 1]; k++); //k是最后一个满足升序的位置
	for (j = k + 1; j < n&&a[j] == b[j]; j++);
	if (j == n) {
		printf("Insertion Sort\n");
		sort(a, a + k + 2);
	}
	else {
		printf("Merge Sort\n");
		int step = 2, flag = 1;
		while (flag) {
			flag = 0;
			for (int i = 0; i < n; i++) {
				if (a[i] != b[i]) flag = 1;
			}
			int i;
			for (i = 0; i < n; i += step) {
				sort(a + i, a + min(i + step, n)); 
			}
			step *= 2;
		}
	}
	for (int i = 0; i < n; i++) {
		cout << a[i];
		if (i != n - 1) cout << " ";
	}
	delete[] a;
	delete[] b;
	return 0;
}
发布了62 篇原创文章 · 获赞 7 · 访问量 3127

猜你喜欢

转载自blog.csdn.net/weixin_43590232/article/details/104132175