PAT甲1098 Insertion or Heap Sort

题意

给定一个数组,和某排序的中间结果
判断是插入排序还是堆排序,并输出下一步操作后的结果

题解

  • 判断是哪种排序,从样例中可以看到插入排序前面部分为部分有序,为后面的数字依旧按原来的排列,根据此入手,找到无序的部分将其和原来相比较,若相同则为插入排序,否则为堆排序
  • 插入排序,找到下一个要操作的元素x,从后往前遍历,大于x则后移,最后再将x赋值到合适位置
  • 堆排序,首要任务是读懂给的样例是什么意思。根据给定的数组,从最后一个非叶节点开始调整建立大顶堆(建堆),然后将堆顶和最后一个元素交换,并调整(排序)。

源码

#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;
int main(){
	int n;
	cin>>n;
	int arr[105],par[105];
	memset(arr,-1,sizeof(arr));
	memset(par,-1,sizeof(par));
	for(int i=1;i<=n;i++){
		int x;cin>>x;
		arr[i]=x;
	}
	for(int i=1;i<=n;i++){
		int x;cin>>x;
		par[i]=x;
	}
	//判断哪种类型 
	int kind=1;
	int index=-1;
	for(int i=1;i<=n;i++){
		if(par[i]<par[i-1]){
			index=i;
			break;
		}
	}
	for(int i=index;i<=n;i++){
		if(arr[i]!=par[i]){
			kind=0; break;
		}
	}
	
	if(kind){
		cout<<"Insertion Sort"<<endl;
		int pos,target;
		for(int i=1;i<=n;i++){
			if(par[i]<par[i-1]){
				pos=i;
				target=par[i];
				break;
			}
		}
		int i;
		for(i=pos;i>=1&&par[i-1]>target;i--){
			par[i]=par[i-1];
		}
		par[i]=target;
		for(i=1;i<n;i++){
			cout<<par[i]<<" ";
		} 
		cout<<par[n]<<endl;
	}else{
		cout<<"Heap Sort"<<endl;
		sort(arr,arr+n+1);
		int pos;
		for(int i=n;i>=1;i--){
			if(arr[i]!=par[i]){
				pos=i;
				break;
			}
		}
		
		int t=par[pos];
		par[pos]=par[1];
		par[1]=t;
		
		int finish=0;
		int change=1;
		pos--;
		while(!finish){
			int l=change*2;
			int r=change*2+1;
			if(l>pos) break; //l越界,说明结束 
			if(r>pos){       //l刚好在界上
				r=0; 		 //par[0]==-1 
			}else{			 //全都在界内 
				if(par[l]<par[change]&&par[r]<par[change]){
					break;
				}
			}
			//堆顶与最后元素交换		
			int z=par[l]>par[r]?l:r;
			t=par[z];
			par[z]=par[change];
			par[change]=t;
			change=z;
		}
		for(int i=1;i<n;i++){
			cout<<par[i]<<" ";
		}
		cout<<par[n]<<endl;
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值