PAT A1098 Insertion or Heap Sort

思路:本题考察堆排序的具体过程。注意题目给出初始序列不包含在中间序列里。堆排序时,若要进行递增排序,首先应该从最后一个非叶结点开始,将其与键值更大的子节点进行互换调整,类似于建立大根堆。建堆之后,每次将堆顶元素放到堆的末尾,将堆大小减一,重复这个过程直到堆的大小为1,排序完成。

#include<cstdio>
#include<algorithm>

using namespace std;

const int maxn = 105;

int origin[maxn];
int temp[maxn];
int intermediate[maxn];
int n;

void printArray(int a[], int size) {
    for(int i = 1; i <= size; i++) {
        printf("%d", a[i]);
        if(i < size) printf(" ");
    }
}

bool isArrEqual(int a[], int b[], int size) {
    for(int i = 1; i <= size; i++)
        if(a[i] != b[i]) return false;
    return true;
}

bool isInsert() {
    bool flag = false;
    for(int i = 2; i <= n; i++) {
        if(i != 2 && isArrEqual(temp, intermediate, n)) 
            flag = true;
        sort(temp + 1, temp + i + 1);
        if(flag) return true;
    }
    return false;
}

void downAdjust(int low, int high) {
    int i = low, j = 2 * i;
    while(j <= high) {
        if(j + 1 <= high && temp[j + 1] > temp[j])
            j = j + 1;
        if(temp[j] > temp[i]) {
            swap(temp[i], temp[j]);
            i = j;
            j = 2 * i;
        } else  {
            break;
        }
    }
}

void HeapSort() {
    for(int i = 1; i <= n; i++)
        temp[i] = origin[i];
    for(int i = n / 2; i >= 1; i--)
        downAdjust(i, n);
    bool flag = false;
    for(int i = n; i > 1; i--) {
        if(i != n && isArrEqual(temp, intermediate, n))
            flag = true;
        swap(temp[i], temp[1]);
        downAdjust(1, i - 1);
        if(flag) return;
    }
}

int main() {
    scanf("%d", &n);
    for(int i = 1; i <= n; i++) {
        scanf("%d", &origin[i]);
        temp[i] = origin[i];
    }
    for(int i = 1; i <= n; i++)
        scanf("%d", &intermediate[i]);
    if(isInsert()) {
        printf("Insertion Sort\n");
        printArray(temp, n);
    } else {
        printf("Heap Sort\n");
        HeapSort();
        printArray(temp, n);
    }
    return 0;
}