PAT甲级刷题记录——1155 Heap Paths (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))
One thing for sure is that all the keys along any path from the root to a leaf in a max/min heap must be in non-increasing/non-decreasing order.
Your job is to check every path in a given complete binary tree, in order to tell if it is a heap or not.

Input Specification:

Each input file contains one test case. For each case, the first line gives a positive integer N (1<N≤1,000), the number of keys in the tree. Then the next line 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, first print all the paths from the root to the leaves. Each path occupies a line, with all the numbers separated by a space, and no extra space at the beginning or the end of the line. The paths must be printed in the following order: for each node in the tree, all the paths in its right subtree must be printed before those in its left subtree.
Finally print in a line Max Heapif it is a max heap, or Min Heapfor a min heap, or Not Heapif it is not a heap at all.

Sample Input 1:

8
98 72 86 60 65 12 23 50

Sample Output 1:

98 86 23
98 86 12
98 72 65
98 72 60 50
Max Heap

Sample Input 2:

8
8 38 25 58 52 82 70 60

Sample Output 2:

8 25 70
8 25 82
8 38 52
8 38 58 60
Min Heap

Sample Input 3:

8
10 28 15 12 34 9 8 56

Sample Output 3:

10 15 8
10 15 9
10 28 34
10 28 12 56
Not Heap

思路

没事干挑了PAT甲级题库的最后一题做(其实是不想写哈夫曼树的题目……),结果感觉这题很简单??(难道是错觉??…),首先,这题的大致题意就是给一棵完全二叉树,先要输出每条根到叶子的路径(每次优先访问右子树),最后输出这个完全二叉树是不是一个堆结构,如果是,对应输出是大顶堆(Max Heap)还是小顶堆(Min Heap),如果不是,就直接输出“Not Heap”。

首先我觉得对于完全二叉树来说,最简单的方法就是直接用数组顺序存储,从1正好顺序存储到N,这个数组就代表了一棵完全二叉树(i的结点的左孩子是2*i,右孩子是2*i+1)。

可能是用了<algorithm>头文件里的is_heap()函数,所以这题需要做的地方完全就是输出根到叶子的路径,我这里还是用DFS来做(DFS重度爱好者……),然后用一个vector容器来存储经过的路径。

因此,DFS的“死胡同”就是当当前结点是叶子结点的时候,就return,具体怎么判断呢,就是当前结点index的左孩子2*index为0,右孩子2*index+1也为0,就说明它没有左孩子也没有右孩子,就是一个叶子结点,于是返回。

那么,“岔路口”怎么走呢,这里需要判断一下,如果存在右孩子,那么就先往右孩子那个方向走,走完之后把路径里右孩子的点pop_back()出来,然后再判断是否存在左孩子,如果存在,那么就往左孩子那个方向走(如果对“岔路口”的走法没有加判断条件的话,路径可能会输出0)。

具体看代码叭~这也是个很简单的题,感觉跟《算法笔记》DFS那节的【走迷宫】很像。

代码

#include<cstdio> 
#include<string>
#include<vector>
#include<algorithm>
#include<iostream>
using namespace std;
const int maxn = 2010;//这里不能写1010,因为假如是每个结点只有右孩子的一棵链式二叉树的话,那最大的结点下标可以到2*1000-1
int V[maxn] = {0};//存放结点点权,V作为静态二叉树 
vector<int> path;
void dfs(int index){//index是数组下标
	if(V[2*index]==0&&V[2*index+1]==0){//如果没有左孩子且没有右孩子,说明当前V[index]是一个叶子结点
		path.push_back(V[index]);
		for(int i=0;i<path.size();i++){//输出根到叶子的路径 
			if(i==0) printf("%d", path[i]);
			else printf(" %d", path[i]);
		}
		printf("\n");
		return;
	} 
	path.push_back(V[index]);//如果不是叶子结点,则先把当前结点的值放入
	if(V[2*index+1]!=0){//如果存在右孩子 
		dfs(2*index+1);//往右孩子方向dfs 
		path.pop_back();
	} 
	if(V[2*index]!=0){//如果存在左孩子 
		dfs(2*index); //往左孩子方向dfs
		path.pop_back();//结束之后记得把路径中的点拿出来 
	}
}
int main(){
	int n;
	scanf("%d", &n);
	for(int i=1;i<=n;i++){
		int tmp;
		scanf("%d", &tmp);
		V[i] = tmp;
	}
	dfs(1);//从下标1开始dfs
	if(is_heap(V+1, V+n+1)==true) printf("Max Heap\n");//判断是否是大顶堆 
	else if(is_heap(V+1, V+n+1, greater<int>())==true) printf("Min Heap\n");//判断是否是小顶堆 
	else printf("Not Heap\n");
    return 0;
}
发布了54 篇原创文章 · 获赞 27 · 访问量 4970

猜你喜欢

转载自blog.csdn.net/weixin_42257812/article/details/105599548