1098 Insertion or Heap Sort
Posted keep23456
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了1098 Insertion or Heap Sort相关的知识,希望对你有一定的参考价值。
判断是否是插入排序的部分与 1035 插入与归并一样。
本题主要考察 堆排序的实现。
首先,把所有双亲结点进行向下调整, 建立大顶堆;
然后,重复 n-1 次操作,即 把堆顶元素与待排序区的最后一个元素交换并对堆顶元素向下调整。
1 #include<iostream> 2 #include<algorithm> 3 using namespace std; 4 5 const int maxn = 200; 6 int n; 7 int origin[maxn],temp[maxn]; 8 9 //向下调整 10 void downAjust(int low,int high) { //low为待调整的双亲结点,high是最后一个叶子结点 11 int i = low,j = i*2; 12 while( j <= high) { 13 //右孩子存在,且大于左孩子 14 if(j + 1 <= high && origin[j+1] > origin[j]) 15 j = j +1; 16 //根结点小于孩子结点 17 if(origin[i] < origin[j]) { 18 swap(origin[i],origin[j]); 19 i = j; 20 j = i*2; 21 } else break; 22 } 23 } 24 25 //建立大顶堆 26 void create() { 27 //从倒数第一个双亲结点 到 根结点进行 向下调整 28 for(int i = n/2; i>=1; --i) 29 downAjust(i,n); 30 } 31 32 int main() { 33 cin>>n; 34 for(int i = 1; i <= n; ++i) 35 cin>>origin[i]; 36 for(int i = 1; i <= n; ++i) 37 cin>>temp[i]; 38 int i,j; 39 for(i = 1; i+1 <= n && temp[i] <= temp[i+1]; ++i); 40 for(j = i+1; j <= n && temp[j] == origin[j]; ++j); 41 if(j > n) { 42 printf("Insertion Sort "); 43 sort(temp+1,temp+i+2); 44 for(i = 1 ; i <= n; ++i) { 45 if(i > 1) printf(" "); 46 printf("%d",temp[i]); 47 } 48 } else { 49 printf("Heap Sort "); 50 create(); //建立大顶堆 51 for(i = n; i > 1; --i) { //堆排序 52 swap(origin[1],origin[i]);//堆顶元素覆盖最后一个元素 53 downAjust(1,i-1); 54 for(j = 1; j <= n && origin[j] == temp[j]; ++j);//中间序列比较 55 if( j > n) break; 56 } 57 --i; 58 swap(origin[1],origin[i]); 59 downAjust(1,i-1); 60 for(i = 1 ; i <= n; ++i) { 61 if(i > 1) printf(" "); 62 printf("%d",origin[i]); 63 } 64 } 65 return 0; 66 }
重新分析题目:
如果是堆排序,可以不用建立大顶堆,而是先找到待排序区的最后一个元素,把堆顶元素与其交换并对堆顶元素向下调整,即可得到题目所要求的下一趟排序序列。
AC代码如下:
1 #include<iostream> 2 #include<algorithm> 3 using namespace std; 4 5 const int maxn = 200; 6 int n; 7 int origin[maxn],temp[maxn]; 8 9 //向下调整 10 void downAjust(int t[],int low,int high) { //low为待调整的双亲结点,high是最后一个叶子结点 11 int i = low,j = i*2; 12 while( j <= high) { 13 //右孩子存在,且大于左孩子 14 if(j + 1 <= high && t[j+1] > t[j]) 15 j = j +1; 16 //根结点小于孩子结点 17 if(t[i] < t[j]) { 18 swap(t[i],t[j]); 19 i = j; 20 j = i*2; 21 } else break; 22 } 23 } 24 25 int main() { 26 cin>>n; 27 for(int i = 1; i <= n; ++i) 28 cin>>origin[i]; 29 for(int i = 1; i <= n; ++i) 30 cin>>temp[i]; 31 int i,j; 32 for(i = 1; i+1 <= n && temp[i] <= temp[i+1]; ++i); 33 for(j = i+1; j <= n && temp[j] == origin[j]; ++j); 34 if(j > n) { 35 printf("Insertion Sort "); 36 sort(temp+1,temp+i+2); 37 } else { 38 printf("Heap Sort "); 39 for( i = n ; i-1 >= 2 && temp[1] <= temp[i]; --i);//找到第一个小于堆顶元素的元素 40 swap(temp[1],temp[i]); //堆顶元素与待排序区的最后一个元素交换 41 downAjust(temp,1,i-1); //向下调整 42 } 43 for(i = 1 ; i <= n; ++i) { 44 if(i > 1) printf(" "); 45 printf("%d",temp[i]); 46 } 47 return 0; 48 }
以上是关于1098 Insertion or Heap Sort的主要内容,如果未能解决你的问题,请参考以下文章
1098 Insertion or Heap Sort (25 分)
PAT 1098 Insertion or Heap Sort (25)
PAT_A1098#Insertion or Heap Sort
1098. Insertion or Heap Sort (25)排序——PAT (Advanced Level) Practise