PTA数据结构与算法题目集(中文) 7-31
7-31 笛卡尔树 (25 分)
笛卡尔树是一种特殊的二叉树,其结点包含两个关键字K1和K2。首先笛卡尔树是关于K1的二叉搜索树,即结点左子树的所有K1值都比该结点的K1值小,右子树则大。其次所有结点的K2关键字满足优先队列(不妨设为最小堆)的顺序要求,即该结点的K2值比其子树中所有结点的K2值小。给定一棵二叉树,请判断该树是否笛卡尔树。
输入格式:
输入首先给出正整数N(≤1000),为树中结点的个数。随后N行,每行给出一个结点的信息,包括:结点的K1值、K2值、左孩子结点编号、右孩子结点编号。设结点从0~(N-1)顺序编号。若某结点不存在孩子结点,则该位置给出−。
输出格式:
输出YES
如果该树是一棵笛卡尔树;否则输出NO
。
输入样例1:
6
8 27 5 1
9 40 -1 -1
10 20 0 3
12 21 -1 4
15 22 -1 -1
5 35 -1 -1
输出样例1:
YES
输入样例2:
6
8 27 5 1
9 40 -1 -1
10 20 0 3
12 11 -1 4
15 22 -1 -1
50 35 -1 -1
输出样例2:
NO
题目分析:一道树的应用题 主要考察的是 对平衡二叉树定义 以及 优先队列(最小堆)定义的理解 对平衡二叉树判断时要注意 不仅要满足每个子树比左边小比右边大 整体树也要满足平衡二叉树的概念
1 #define _CRT_SECURE_NO_WARNINGS 2 #include<stdio.h> 3 #include<string.h> 4 #include<malloc.h> 5 6 struct TreeNode 7 { 8 int K1; 9 int K2; 10 int Lc; 11 int Rc; 12 }Tr[1000]; 13 14 int Collected[1000]; 15 16 int FindTree(int N) 17 { 18 for (int i = 0; i < N; i++) 19 if (!Collected[i]) 20 return i; 21 } 22 23 24 25 int IsAVL(int Tree) 26 { 27 if (Tree ==-1) 28 return 1; 29 else 30 { 31 if (Tr[Tree].Lc != -1 && Tr[Tree].Rc != -1) 32 if (Tr[Tree].K1 >=Tr[Tr[Tree].Lc].K1 && Tr[Tree].K1 < Tr[Tr[Tree].Rc].K1) 33 return IsAVL(Tr[Tree].Lc) && IsAVL(Tr[Tree].Rc); 34 else 35 return 0; 36 else if (Tr[Tree].Lc == -1 && Tr[Tree].Rc == -1) 37 return 1; 38 else if (Tr[Tree].Lc == -1) 39 return Tr[Tree].K1 < Tr[Tr[Tree].Rc].K1; 40 else 41 return Tr[Tree].K1 >=Tr[Tr[Tree].Lc].K1; 42 43 } 44 } 45 46 int IsMinHeap(int Tree) 47 { 48 if (Tree ==-1) 49 return 1; 50 else 51 { 52 if (Tr[Tree].Lc != -1 && Tr[Tree].Rc != -1) 53 if (Tr[Tree].K2 <=Tr[Tr[Tree].Lc].K2 && Tr[Tree].K2 <=Tr[Tr[Tree].Rc].K2) 54 return IsMinHeap(Tr[Tree].Lc) && IsMinHeap(Tr[Tree].Rc); 55 else 56 return 0; 57 else if (Tr[Tree].Lc == -1 && Tr[Tree].Rc == -1) 58 return 1; 59 else if (Tr[Tree].Lc == -1) 60 return Tr[Tree].K2 <=Tr[Tr[Tree].Rc].K2; 61 else 62 return Tr[Tree].K2 <=Tr[Tr[Tree].Lc].K2; 63 } 64 } 65 int JudgetLeft(int Tree, int T); 66 int JudgetRight(int Tree, int T); 67 68 int JudgetLeft(int Tree,int T) 69 { 70 if (T == -1 || Tree == -1) 71 return 1; 72 if (Tr[Tree].K1 > Tr[T].K1) 73 return JudgetLeft(Tree, Tr[T].Lc) && JudgetLeft(Tree,Tr[T].Rc); 74 else 75 return 0; 76 } 77 78 int JudgetRight(int Tree, int T) 79 { 80 if (T == -1 || Tree == -1) 81 return 1; 82 if (Tr[Tree].K1 < Tr[T].K1) 83 return JudgetRight(Tree, Tr[T].Lc) && JudgetRight(Tree, Tr[T].Rc); 84 else 85 return 0; 86 } 87 88 int IsTree(int Tree) 89 { 90 if (Tree == -1) 91 return 1; 92 if(JudgetLeft(Tree,Tr[Tree].Lc)&&JudgetRight(Tree,Tr[Tree].Rc)) 93 return IsTree(Tr[Tree].Lc)&&IsTree(Tr[Tree].Rc); 94 else 95 return 0; 96 } 97 98 int main() 99 { 100 int N; 101 scanf("%d", &N); 102 for (int i = 0; i < N; i++) 103 { 104 int K1, K2, Lc, Rc; 105 scanf("%d%d%d%d", &K1, &K2, &Lc, &Rc); 106 Tr[i].K1 = K1; 107 Tr[i].K2 = K2; 108 Tr[i].Lc = Lc; 109 Tr[i].Rc = Rc; 110 if (Lc != -1) 111 Collected[Lc] = 1; 112 if (Rc != -1) 113 Collected[Rc] = 1; 114 } 115 int Tree = FindTree(N); 116 if (IsAVL(Tree) && IsMinHeap(Tree)&&IsTree(Tree)) 117 printf("YES"); 118 else 119 printf("NO"); 120 return 0; 121 }