1. 程式人生 > >PAT-1098(Insertion Or Heap Sort)

PAT-1098(Insertion Or Heap Sort)

include ons als rac http 特征 插入排序 處理 [0

  題目鏈接見這裏

  分析:考察的是插入排序堆排序兩種基本的數據結構,註意利用兩種排序的基本特征----插入排序不影響全局,而堆排序影響全局

#include <stdio.h>
#define SWAP(a,b) a = b-a+(b=a) 
#define N 105 

void Input(int *unSorted, int partialSorted[], int *n){
	int i;
	scanf("%d",n);
	for(i=1;i<=*n;i++) scanf("%d",&unSorted[i]);
	for(i=1;i<=*n;i++) scanf("%d",&partialSorted[i]);
}

void AdjustDown(int *partialSorted, int k, int n){
	//將元素k向下進行調整
	int i;
	partialSorted[0] = partialSorted[k]; //partialSorted[0]暫存
	for(i=2*k;i<=n;i*=2){ //沿key較大的子結點向下篩選
		if(i<n && partialSorted[i]<partialSorted[i+1]) 
			i ++; //取key值較大的子結點的下標
		if(partialSorted[0]>=partialSorted[i]) break; //篩選結束
		else{
			partialSorted[k] = partialSorted[i]; //將partialSorted[i]調整到雙親結點上
			k = i; //修改k值,以便繼續向下篩選
		} 
	} 
	partialSorted[k] = partialSorted[0]; //被篩選結點的值放入最終的位置 
} 

void BuildMaxHeap(int *partialSorted, int n){
	int i = n/2;
	for(;i>0;i--) //從i=[n/2]~1,反復調整堆
		AdjustDown(partialSorted,i,n); 
}

int HeapSort(int *unSorted, int *partialSorted, int n){  
	int index = n;
	for(;index>1 && partialSorted[index-1]<=partialSorted[index];index--);
	//進入下一次叠代 
	BuildMaxHeap(partialSorted,index); //asending:大頂堆
	SWAP(partialSorted[index],partialSorted[1]); //輸出堆頂元素(和堆底元素交換) 
	AdjustDown(partialSorted,1,index-1); //整理,把剩余的index-2個元素整理成堆
	printf("Heap Sort\n"); 
}

int InsertionSort(int unSorted[], int partialSorted[], int n){
	int i,j,index,low,high,mid;
	for(i=1;i<n && partialSorted[i]<=partialSorted[i+1];i++);
	index = ++i;
	for(;i<=n && unSorted[i]==partialSorted[i];i++);
	if(i>n){
		//折半插入(穩定) 
		partialSorted[0] = partialSorted[index]; //暫存partialSorted[index] 
		low = 1, high = index-1;
		while(low<=high){
			mid = (low+high)/2; //取中間點 
			if(partialSorted[mid]>partialSorted[0]) high = mid-1; //查找左半子表 
			else low = mid+1; //查找右半子表 
		}
		for(j=index-1;j>=high+1;j--)
			partialSorted[j+1] = partialSorted[j]; //統一後移元素,空出插入位置
		partialSorted[high+1] = partialSorted[0];
		printf("Insertion Sort\n");
		return 1;
	}	
	return 0;
}

void Show(int partialSorted[], int n){
	int i;
	for(i=1;i<=n;i++){
		printf("%d",partialSorted[i]);
		if(i==n) printf("\n");
		else printf(" ");
	}
}

int main(){
	int unSorted[N],partialSorted[N];
	int n;
//	freopen("Data.txt","r",stdin); //段錯誤 
	Input(unSorted,partialSorted,&n);
	//模擬來判斷unSorted和partialSorted相等是非常愚蠢的行為 
	//運用一下堆排序和插入排序的特征,處理問題更快捷 
	//先做插入排序的判斷,然後進行堆排序
	//插入排序不影響全局,而堆排序影響全局(亦即無法根據特征性質判斷是否為堆排序)
	if(InsertionSort(unSorted,partialSorted,n));
	else HeapSort(unSorted,partialSorted,n);
	Show(partialSorted,n);
	return 0;
}

PAT-1098(Insertion Or Heap Sort)