PAT A 1098. Insertion or Heap Sort (25)

题目

According to Wikipedia:

Insertion sort iterates, consuming one input element each repetition, and growing a sorted output list. Each iteration, insertion sort removes one element from the input data, finds the location it belongs within the sorted list, and inserts it there. It repeats until no input elements remain.

Heap sort divides its input into a sorted and an unsorted region, and it iteratively shrinks the unsorted region by extracting the largest element and moving that to the sorted region. it involves the use of a heap data structure rather than a linear-time search to find the maximum.

Now given the initial sequence of integers, together with a sequence which is a result of several iterations of some sorting method, can you tell which sorting method we are using?

Input Specification:

Each input file contains one test case. For each case, the first line gives a positive integer N (<=100). Then in the next line, N integers are given as the initial sequence. The last line contains the partially sorted sequence of the N numbers. It is assumed that the target sequence is always ascending. All the numbers in a line are separated by a space.

Output Specification:

For each test case, print in the first line either "Insertion Sort" or "Heap Sort" to indicate the method used to obtain the partial result. Then run this method for one more iteration and output in the second line the resuling sequence. It is guaranteed that the answer is unique for each test case. All the numbers in a line must be separated by a space, and there must be no extra space at the end of the line.

Sample Input 1:

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

Sample Output 1:

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

Sample Input 2:

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

Sample Output 2:

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


判断插入排序还是堆排序,和之前的插入排序和快速排序比较很相似,只是把快排变成了堆排序。

首先判断下是否为快排,是则再迭代一步。

否则必然是堆排序了,由于堆排序排序后的部分放在尾部,而第一个元素始终是未排序的最大元素。

所以,从后依次向前,找到第一个小于第一个元素的数即为未排序序列(最大堆)的尾。

交换两者,然后修正最大堆即可。


代码:

这里偷懒,由于数据量不大,直接调用sort进行了插入排序

#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

bool isSame(vector<int> &v1,vector<int> &v2);	//比较两个序列是否相同

int main()
{
	int n;
	cin>>n;
	vector<int> first(n,0),second(n,0),tv1;	//第一组,第二个组,临时数据
	vector<int>::iterator ivi;
	for(int i=0;i<n;i++)	//输入
		cin>>first[i];
	for(int i=0;i<n;i++)
		cin>>second[i];

	tv1=first;
	for(int i=0;i<n;i++)	//判断插入排序
	{
		sort(tv1.begin(),tv1.begin()+i+1);	//不断插入,对比
		if(isSame(tv1,second))
		{
			for(i++;i<n;i++)	//!!!要找一个结果改变的项
			{
				ivi=tv1.begin()+min(n,i+1);
				sort(tv1.begin(),ivi);
				if(!isSame(tv1,second))	//结果改变,输出
					break;
			}
			cout<<"Insertion Sort\n";
			cout<<tv1[0];
			for(int j=1;j<n;j++)
				cout<<" "<<tv1[j];
			return 0;
		}
	}

	cout<<"Heap Sort\n";	//二选一,只能是堆排序了
	tv1=second;
	int pos=0,max,last=0;	//堆需要修正的位置,需要修正位置和两个子节点中的最大置为,堆的最后一个元素的位置
	for(int i=n-1;i>=0;i--)	//查找堆的最后一个元素
	{
		if(second[i]<second[0])
		{
			last=i;
			break;
		}
	}
	swap(tv1[0],tv1[last]);	//交换
	while(pos<last)		//修正最大堆
	{
		max=pos;
		if(pos*2+1<last&&tv1[pos*2+1]>tv1[max])
			max=pos*2+1;
		if(pos*2+2<last&&tv1[pos*2+2]>tv1[max])
			max=pos*2+2;
		if(max==pos)
			break;
		swap(tv1[pos],tv1[max]);
		pos=max;
	}
	cout<<tv1[0];	//输出
	for(int j=1;j<n;j++)
		cout<<" "<<tv1[j];

	return 0;
}

bool isSame(vector<int> &v1,vector<int> &v2)
{
	for(int i=0;i<v1.size();i++)
		if(v1[i]!=v2[i])
			return false;
	return true;
}





你可能感兴趣的:(C++,算法,pat)