给定一个待排序序列和排序若干次的序列,要求判断是获得目标序列是经过插入排序仍是堆排序,而后在输出再排序一次后的序列便可。算法
这里考察的就是插入排序和堆排序的完整排序的过程,循序渐进的来就好。函数
首先将序列划分为有序序列部分和无序序列部分,初始有序序列为序列中第一个元素,对于长度为N的序列,插入排序会通过N-1趟排序,完成将N-1个无序序列的元素依次插入到有序序列之中,那么能够看到,插入排序分为外部循环控制趟数,内部循环负责找到插入位置,每次循环使用t暂存待插入元素,而后在$[1,j]$(有序序列)中查询待插入位置loc,只要$t>=temp[j]$,说明找到插入位置$j+1$,退出内层循环,将$j+1$位置的元素赋值为t便可。spa
因为目标序列是递增系列,那么咱们须要创建大根堆,咱们初始序列做为大根堆的层序遍历序列,而后从最后一个非叶子节点到根节点,依次向下调整,只要孩子节点中有比当期父节点大的,就交换孩子节点和父节点,而且向下依次递推查询,直到孩子节点的权重均比父节点小中止调整。这样就完成了初始大根堆的创建过程。堆排序就是将根节点和最后一个节点(未排序节点)进行交换,而后再向下调整根节点。这样就完成了一次堆排序的过程,每一次堆排序都会固定一个最大的元素在最后。code
因为题目要求判断已排序部分的序列是插入排序仍是堆排序的结果之上再进行一次排序,那么咱们使用$same$标志已排序的部分序列是不是由当前的排序算法获得的,若是在排序完成后,判断$same$为$true$,那么就说明能够退出排序过程,进行相应的输出。若是$same$为$false$,那么就使用$isSame$函数更新$same$的值。blog
#include <cstdio> #include <algorithm> using namespace std; int N;// 节点个数 int init[105];//初始序列 int temp[105];//暂存初始序列 int partial_sorted[105];//部分排序序列 bool isSame(){ for (int i = 1; i <= N; ++i) { if(temp[i]!=partial_sorted[i]){ return false; } } return true; } bool InsertionSort(){ bool same = false; // N-1轮排序 for (int i = 1; i < N; ++i) { int t = temp[i+1];//暂存待插入元素 int loc = 1;// 待插入位置,初始为1,考虑3 1的特殊状况 for (int j = i; j >= 1; --j) { if(t<temp[j]){ temp[j+1] = temp[j]; } else { // 找到插入位置 loc = j+1; break; } } temp[loc] = t; if(same){ // 在相等的状况下,又排序了一次 break; } if(isSame()) same = true;//已经相同了,再排序一次 } return same; } // 调整[low,high]的节点权重,low从最后一个非叶节点开始一直到1,high为当前堆须要调整的最后一个元素 void downAdjust(int low,int high){ int i = low; int j = 2*i;//i的左孩子 while (j<=high){ // 只要左孩子一直存在,就向下调整 if(j+1<=high&&temp[j+1]>temp[j]){ // 右孩子节点更小 j = j+1; } if(temp[j]>temp[i]){ // 孩子节点的值更小 swap(temp[j],temp[i]); i = j; j = 2*i; }else { // 孩子权重更加小,就中止比较 break; } } } void createHeap(){ for(int i=N/2;i>=1;--i){ downAdjust(i,N); } } void print(){ for(int i=1;i<=N;++i){ printf("%d",temp[i]); if(i<N) printf(" "); } } void HeapSort(){ createHeap();//先建堆 // 将最后的节点和堆顶的节点交换,而后调整 bool same = false; for(int i=N;i>=2;--i){ swap(temp[i],temp[1]); downAdjust(1,i-1); if(same){ printf("Heap Sort\n"); print(); break; } if(isSame()){ same = true; } } } int main() { scanf("%d",&N); for (int i = 1; i <= N; ++i) { scanf("%d",&init[i]); temp[i] = init[i]; } for (int i = 1; i <= N; ++i) { scanf("%d",&partial_sorted[i]); } if(InsertionSort()){ printf("Insertion Sort\n"); print(); } else { // 重置temp for (int i = 1; i <= N; ++i) { temp[i] = init[i]; } HeapSort(); } return 0; }