PAT甲级-1147 Heaps(30 分)

1147 Heaps(30 分)
In computer science, a heap is a specialized tree-based data structure that satisfies the heap property: if P is a parent node of C, then the key (the value) of P is either greater than or equal to (in a max heap) or less than or equal to (in a min heap) the key of C. A common implementation of a heap is the binary heap, in which the tree is a complete binary tree. (Quoted from Wikipedia at https://en.wikipedia.org/wiki/Heap_(data_structure))

Your job is to tell if a given complete binary tree is a heap.

Input Specification:
Each input file contains one test case. For each case, the first line gives two positive integers: M (≤ 100), the number of trees to be tested; and N (1 < N ≤ 1,000), the number of keys in each tree, respectively. Then M lines follow, each contains N distinct integer keys (all in the range of int), which gives the level order traversal sequence of a complete binary tree.

Output Specification:
For each given tree, print in a line Max Heap if it is a max heap, or Min Heap for a min heap, or Not Heap if it is not a heap at all. Then in the next line print the tree’s postorder traversal sequence. All the numbers are separated by a space, and there must no extra space at the beginning or the end of the line.

https://pintia.cn/problem-sets/994805342720868352/problems/994805342821531648
Sample Input:
3 8
98 72 86 60 65 12 23 50
8 38 25 58 52 82 70 60
10 28 15 12 34 9 8 56
Sample Output:
Max Heap
50 60 65 72 12 23 86 98
Min Heap
60 58 52 38 82 70 25 8
Not Heap
56 12 34 28 9 8 15 10

#include<bits/stdc++.h>
const int max_n=100,max_tn=1000; //最多有100棵树,每棵树最多有1000个结点
int n,tn; //n棵树,每棵tn个结点
int no[max_tn]; //存一棵树

/*判断一个结点的左右孩子是否更大*/
int is_max; //假设该树是大根堆,则取值1,否则取值0
void max_heap(int no[],int cur){ 
  if(cur>=tn) return; //非法下标,结束函数
  int left = cur*2+1,right = cur*2+2;
  if((left<tn&&no[left]>no[cur]) || (right<tn&&no[right]>no[cur])){
    is_max=0; //左或右孩子比父节点大,则非大根堆
    return; //结束判断
  }
    max_heap(no,left); //检查左结点
    max_heap(no,right); //检查右结点
}

/*判断一个结点的左右孩子是否更小*/
int is_min; //假设该树是小根堆,则取值1,否则取值0
void min_heap(int no[],int cur){ 
  if(cur>=tn) return; //非法下标,结束函数
  int left = cur*2+1,right = cur*2+2;
  if((left<tn&&no[left]<no[cur]) || (right<tn&&no[right]<no[cur])){
    is_min=0; //左或右孩子比父节点小,则非小根堆
    return; //结束判断
  }
    min_heap(no,left); //检查左结点
    min_heap(no,right); //检查右结点
}

/*后序遍历*/
void postorder(int no[],int cur){
  if(cur >= tn) return; //非法下标,结束
  postorder(no,2*cur+1); //后序遍历左子树
  postorder(no,2*cur+2); //后序遍历右子树  
  printf("%d",no[cur]); //打印父结点
  if(cur == 0)printf("\n"); //首位后打印换行 
  else printf(" "); //非首位,则其后打印空格

}
int main(){
  /*接收数据*/
  scanf("%d %d",&n,&tn);
  for(int j = 0; j < n; j++){
    for(int i=0;i<tn;i++){
    scanf("%d",&no[i]);
  }

  /*判断是否大根堆*/
  is_max = 1; //假设该树是大根堆
  max_heap(no,0);
  if(is_max == 1){ //确实大根堆
    printf("Max Heap\n");
  } else{ //非大根堆
    is_min = 1; //假设该树是小根堆
    min_heap(no,0);   
    if(is_min == 1){//确实小根堆
      printf("Min Heap\n");
    }else{ //非小根堆
     printf("Not Heap\n");
    }
  }

  /*后序遍历*/
   postorder(no,0);
  }

  return 0;
}

这里写图片描述

猜你喜欢

转载自blog.csdn.net/yeziand01/article/details/80888983