[PAT解题报告] Insertion or Heap Sort
和1089差不多……也是判断插入排序,另外一种排序是堆排序。关于插入排序,和1089判断方法相同,不过这次我没有对每个前i项单独排序,而是模拟了插入排序的过程,直到找到和输入相等的时候,再继续到第一个不同的时候。
对于堆排序也是模拟,每次deleteMax,把最大的放入堆的最后,并且把堆的size减小1,这样每次后缀都是排好顺序的,关键是实现堆排序的down函数,就是把某个位置(可能)不符合要求的下移动,维护堆的性质。比1089还是难一些,因为堆排序相对难写。
代码:
#include <cstdio> #include <cstring> #include <string> #include <algorithm> using namespace std; int a[102], b[102], c[102]; void print(int *a, int n) { for (int i = 0; i < n; ++i) { if (i) { putchar(' '); } printf("%d", a[i]); } puts(""); } bool same(int *a,int *b, int n) { for (int i = 0; i < n; ++i) { if (a[i] != b[i]) { return false; } } return true; } void insertion(int *a, int i) { int temp = a[i]; for (--i; (i >= 0) && (a[i] > temp); --i) { a[i + 1] = a[i]; } a[i + 1] = temp; } bool make1(int n) { bool mark = false; for (int i = 1; i < n; ++i) { insertion(c, i); if (same(c, b, n)) { mark = true; } else if (mark) { puts("Insertion Sort"); print(c, n); return true; } } return false; } void down(int *a, int i, int n) { for (;;) { int left = (i << 1) | 1; if (left >= n) { break; } int right = left + 1; int x = ((right < n) && (a[right] > a[left]))?right:left; if (a[i] > a[x]) { break; } swap(a[x], a[i]); i = x; } } void deleteMax(int *a,int &n) { swap(a[0], a[--n]); down(a, 0, n); } void make2(int n) { puts("Heap Sort"); for (int i = (n >> 1) - 1; i >= 0; --i) { down(a, i, n); } int m = n; while (!same(a, b, n)) { deleteMax(a, m); } while (same(a, b, n)) { deleteMax(a, m); } print(a, n); } int main() { int n; scanf("%d", &n); for (int i = 0; i < n; ++i) { scanf("%d", a + i); } memcpy(c, a, sizeof(int) * n); for (int i = 0; i < n; ++i) { scanf("%d", b + i); } if (!make1(n)) { make2(n); } return 0; }
原题链接; http://www.patest.cn/contests/pat-a-practise/1098