1098 Insertion or Heap Sort C++版

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

1098 Insertion or Heap Sort C++版

1.题意

给出两个数组值,让你判断第二个数组的值是根据插入排序还是堆排序从第一个数组得到的。

2.分析

这题同之前的一道pat很相似,不过前一道pat是判断插入排序和归并排序。不过道理都是雷同的,需要注意的是:堆排序的实现。
如果得到这个序列是由堆排序得到的中间序列,那么该怎么进行下一步排序呢?我最开始的想法是:找到一个这个堆排序的下限K,然后对前K个数字进行一个堆排序就ok,但是问题是,如何找到这样的一个数字K。比如给出下面这串序列:
6 4 5 1 0 3 2 7 8 9。我思索了很久,没有发现是没有一种很好的方法解决这个问题的,于是只能使用最笨的方法,进行一次堆排序,比较中间序列是否相同,如果相同,然后再多排序一次,就得到了目的数组。

3.代码

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

int heap[maxn];
int part[maxn];
int N;

int isInsert(){//判断是否是插入排序 
	int i ,index = 0;	
	for(i = 1;i < N; i++){//上限只到N-1
		//cout << i<<" ";
		if(part[i+1] < part[i]){//如果前面的序列呈递增 						
			i++;
			index = i;
			break;
		}
	}
	for(;i <= N;i++){//判断后面的序列是否完全相同 
		if(part[i] != heap[i]){
			return 0;//表示是堆排序 
		}
	}
	return index;//表示是插入排序 
}

//找到堆排序的上限n  --> 事实证明太麻烦了 
int isSame(){
	for(int i = 1;i <= N ;i++){ 
		if(part[i] != heap[i]){//
			return 0;			
		}
	}
	return 1;//表示相等 
} 

//插入排序 ,待插入的项的下标 是index
void insertSort(int index){
	//cout <<"index = "<<index<<"\n";
	int temp = part[index];
	for(int i= 1; i <= N;i++){
		if(part[i] > part[index]){//如果当前项大于index项 
			for(int j = index; j >=i; j--){//循环移位 
				part[j] = part[j-1];
			} 
			part[i] = temp; 
			break;
		}
	}
}

//向下调整 
void downAdjust(int low,int high){
	int i = low,j = i* 2;
	while(j <= high){//循环向下调整 
		//如果右孩子存在,且右孩子值大于左孩子
		if(j+1 <= high && heap[j+1] > heap[j]){
			j=j+1;//这里加1的原因是,想使用下面这段比较且交换的公用代码 
		}		
		//如果孩子中最大的权值比欲调整节点i大
		if(heap[j] > heap[i]){
			swap(heap[j],heap[i]);
			i = j;
			j = i * 2;//跟本方法中第一行的 j=i*2同道理 
		} else{
			break;//调整结束 
		}
	} 
}

void creatHeap(int n){
	for(int i = n/2;i >=1 ;i--){
		downAdjust(i,n);
	}
}

//打印下一次排序后,数组的信息 
void printHeap(int array[]){	
	for(int i = 1;i<= N;i++){
		if(i!=N) cout << array[i]<<" ";
		else cout << array[i];
	}cout<<"\n"; 
} 
	
void heapSort(int n){	
	creatHeap(n);	
	for(int i = n;i> 1;i--){//倒着枚举,直到堆中只有一个元素 
		swap(heap[i],heap[1]);//交换heap[i] 与堆顶
		downAdjust(1,i-1);//调整堆顶 
		if(isSame()) {//说明已经完全一样了,还需要再调整一次 
			//cout <<"is same...\n";
			//cout <<"i = "<<i<<endl;
			i--;
			swap(heap[i],heap[1]);
			downAdjust(1,i-1);//调整堆顶 
			break;
		}
	}
}


int main(){	
	cin >> N;
	int i ;	
	for(i = 1;i <=N ;i++){
		cin >> heap[i];
	}
	for(i = 1;i <=N ;i++){
		cin >> part[i];
	}
	if(isInsert()){//说明是插入排序 
		cout <<"Insertion Sort\n";
		insertSort(isInsert());
		printHeap(part);
	}
	else{		
		cout <<"Heap Sort\n";
		heapSort(N);
		printHeap(heap);
	} 
}

4.测试用例

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


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

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

5.执行结果

在这里插入图片描述

猜你喜欢

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