笛卡尔树 中序遍历判断是否为二叉搜索树
来源:互联网 发布:做报表的软件 编辑:程序博客网 时间:2024/06/05 05:06
笛卡尔树是一种特殊的二叉树,其结点包含两个关键字K1和K2。首先笛卡尔树是关于K1的二叉搜索树,即结点左子树的所有K1值都比该结点的K1值小,右子树的所有K1值都比该结点的K1值大。其次所有结点的K2值满足优先队列(不妨设为最小堆)的顺序要求,即该结点的K2值比其子树中的所有K2值小。给定一棵二叉树,请判定该树是否笛卡尔树。
1.实验要求
(1)输入说明:
输入第一行中给出正整数N(N<=1000),为树中结点总数。随后N行,每行给出q一个结点的信息,包括:结点的K1值、K2值、左孩子结点编号、右孩子结点编号。设结点从0-(N-1)编号。若某结点不存在孩子结点,则该位置给出-1。
(2)输出说明:
如果该树是一棵笛卡尔树则输出YES,否则输出NO。
(3)测试用例:
输入: 输出:
序号
输入
输出
说明
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
YES
一般情况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
NO
一般情况NO测试
3
6
8 27 5 1
9 40 -1 -1
10 20 0 3
12 21 -1 4
11 22 -1 -1
5 35 -1 -1
NO
K2满足最小堆顺序,但K1不满足二叉搜索树
4
9
11 5 3 -1
15 3 4 7
5 2 6 0
6 8 -1 -1
9 6 -1 8
10 1 2 1
2 4 -1 -1
20 7 -1 -1
12 9 -1 -1
NO
K2满足最小堆顺序;K1的每个子树都满足二叉搜索树条件,但整棵树不满足二叉搜索树条件------即简单的后序遍历不能给出正确结果
5
1
1 1 -1 -1
YES
边界测试:最小N
4.解决思路:
(1)问题分析
本题主要分两个子问题:1.根据输入的信息建立二叉树2.根据树的结构判断其是否满足笛卡尔树的性质。
判断其是否满足笛卡尔树的性质:
需要分别对K1,K2进行判断。
对K1键值进行中序遍历,边遍历边比较,若遍历结果为递增有序,则是一个二叉搜索树,只要有不符,则不是二叉搜索树。
对K2键值进行后序遍历,先检查左、右子树是否都满足条件,若是,则将当前结点的K2值与左右子树的K2最小值比较,确定是否满足条件;否则返回No。
(2)实现要点
a.用数组实现二叉树的存储:
注意到题目是用0-(N-1)整型编号代表树的结点的,所以可以把每个结点的信息存储在元素结构体的数组里,将结构体中的左右孩子域定义为整型。
b.数组实现二叉树的根的表示:
由于题目没有直接说明哪个结点是根,所以需要在建树过程中确定根结点信息。可以为每个结点建立一个标记tag,初始化为1(即每一个结点都有可能是根结点)。在建立树的过程中,不断将是左右孩子结点的tag设置为0(即有父结点的不是根)。建树完成后,扫描一遍所有结点的tag,唯一一个tag不为0的结点,就是根结点。
#include<stdio.h>struct node{int k1;int k2;int left;int right;int tag=1;}tree[1010];int CreatTree(int n){for(int i=0;i<n;i++){scanf("%d%d%d%d",&tree[i].k1,&tree[i].k2,&tree[i].left,&tree[i].right);if(tree[i].left!=-1) tree[tree[i].left].tag=0;if(tree[i].right!=-1) tree[tree[i].right].tag=0;}for(int i=0;i<n;i++){if(tree[i].tag) return i;}}int Flag1=1;int IsBstree(int root){if(tree[root].left==-1&&tree[root].right==-1) return tree[root].k1; if(tree[root].left!=-1) { int TmpLeft=IsBstree(tree[root].left);if(tree[root].k1<TmpLeft||tree[root].k1==TmpLeft) Flag1=0; } if(tree[root].right==-1) return tree[root].k1;int TmpRight=IsBstree(tree[root].right);if(tree[root].k1>TmpRight||tree[root].k1==TmpRight) Flag1=0;return TmpRight;}int Flag2=1;int IsMinHeap(int root){int MinLeft,MinRight;int TmpMin;if(tree[root].left==-1&&tree[root].right==-1) return tree[root].k2;else if(tree[root].left!=-1&&tree[root].right==-1) { MinLeft=IsMinHeap(tree[root].left); if(tree[root].k2>TmpMin||tree[root].k2==TmpMin) Flag2=0; return TmpMin;}else if(tree[root].right!=-1&&tree[root].left==-1) { MinRight=IsMinHeap(tree[root].right); if(tree[root].k2>TmpMin||tree[root].k2==TmpMin) Flag2=0; return TmpMin;}else {MinLeft=IsMinHeap(tree[root].left);MinRight=IsMinHeap(tree[root].right);TmpMin = MinLeft<MinRight?MinLeft:MinRight;if(tree[root].k2>TmpMin||tree[root].k2==TmpMin) Flag2=0; return TmpMin; } }int main(){int n;scanf("%d",&n);int root= CreatTree(n);IsBstree(root);IsMinHeap(root);if(Flag1&&Flag2) printf("YES\n");else printf("NO\n");return 0;}用flag1和flag2是因为在递归的时候要return k1,k2值来与上一层次比较,无法return false/true来判断是否为二叉搜索树/最小堆。在网上搜索中序遍历判断是否为二叉搜索树,发现有两种方法,一种是多开一个数组保存中序遍历结果,然后再对数组里的值进行遍历比较。第二种方法是递归时return false/true,前驱结点的值用static 来保存。
//判断是否为BSTbool isBST(Node* root){ static Node *prev = NULL; // 中序遍历这棵树,并保存前驱节点至prev中 if (root) { if (!isBST(root->left)) return false; // 检测节点值的合法性 if (prev != NULL && root->key <= prev->key) return false; prev = root; //右子树 return isBST(root->right); } return true;}
- 笛卡尔树 中序遍历判断是否为二叉搜索树
- 判断二叉搜索树是否为后序遍历序列
- 判断是否为二叉搜索树的后序遍历
- 输入一个数列,判断是否为某一个二叉搜索树的后序遍历序列
- 判断给定的数组是否为二叉搜索树的后序遍历序列
- 判断某序列是否为某二叉搜索树的后序遍历
- 剑指offer——判断一个序列是否为二叉搜索树的后序遍历
- 剑指offer 判断数组的后序遍历是否为搜索二叉树
- 判断数组是否为搜索二叉树的后序遍历
- 关于判断某一数组内容是否为一个二叉搜索树的后序遍历结果
- 判断是否是二叉搜索树的后序遍历
- 判断是否二叉搜索树的后序遍历
- 判断一颗树是否为二叉搜索树
- 判断一棵树是否为二叉搜索树
- 判断一颗树是否为二叉搜索树
- 二叉树问题---判断数组是否为某搜索二叉树的后序遍历的结果
- 层序遍历判断是否为完美二叉树
- 二叉搜索树的后序遍历序列序列判断是否是二叉搜索树
- MacBook使用
- 判断最小生成树的唯一性
- 第十五周-C语言习题 字符串比较
- [bzoj 3122] [Sdoi2013]随机数生成器:数论,同余,分类讨论,BSGS
- HTTP与HTTPS协议介绍
- 笛卡尔树 中序遍历判断是否为二叉搜索树
- Spring boot + thymeleaf + Shiro 会话过期返回登录界面片段之解决方案
- 《我的人生哲学:马云献给年轻人的12堂人生智慧课》读后感
- 第十五周-包含B的字符串
- TCP三次握手过程
- jQuery 列表的修改和添加
- 【PHP】用unset销毁变量
- android studio开发 Toast消息和控制台输出内容出现乱码解决方案
- BZOJ 2002: [Hnoi2010]Bounce 弹飞绵羊 LCT