• 数据结构与算法题目集(中文)7-31 笛卡尔树 (25分) (二叉搜索+最小堆 注意建树方式、二叉搜索树的中序遍历是由小到大的)


    1.题目

    笛卡尔树是一种特殊的二叉树,其结点包含两个关键字K1和K2。首先笛卡尔树是关于K1的二叉搜索树,即结点左子树的所有K1值都比该结点的K1值小,右子树则大。其次所有结点的K2关键字满足优先队列(不妨设为最小堆)的顺序要求,即该结点的K2值比其子树中所有结点的K2值小。给定一棵二叉树,请判断该树是否笛卡尔树。

    输入格式:

    输入首先给出正整数N(≤1000),为树中结点的个数。随后N行,每行给出一个结点的信息,包括:结点的K1值、K2值、左孩子结点编号、右孩子结点编号。设结点从0~(N-1)顺序编号。若某结点不存在孩子结点,则该位置给出−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

    2.题目分析

    1.注意题目中的建树方式,是给了节点的左右节点编号,就需要设置一个数组,在输入的时候向节点各个位置赋值,最后未赋值的就是根节点通过建立一个数组来寻找根节点 同 7-3 树的同构 (25分)https://pintia.cn/problem-sets/15/problems/711

    2.二叉搜索树的中序遍历是由小到大的,使用两个数组分别获取其中序遍历的结果,之后将其中一个进行排序,如果排序之后还与第二个数组相同就说明是二叉搜索树

    3.最小堆的判别是通过递归,分别看左右子树的数字是否大于根节点

    3.代码

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    struct node 
    {
    	int num;
    	int k1;
    	int k2;
    	int left;
    	int right;
    }people[1001];
    
    int ishead[1001];
    int order1[1001];
    int order2[1001];
    
    bool idsearch = true;
    int len = 0;
    void find(int head)
    {
    	if (head != -1)
    	{
    		find(people[head].left);
    		order1[len] = people[head].k1;
    		order2[len++] = people[head].k1;
    		find(people[head].right);
    	}
    }
    
    bool isheap = true;
    void find2(int head)
    {
    	if (people[head].left != -1)
    	{
    		int 	left = people[head].left;
    		if (people[left].k2 < people[head].k2)
    		{
    			isheap = false;
    			return;
    		}
    		find2(left);
    	}
    	if (people[head].right != -1)
    	{
    		int 	right = people[head].right;
    		if (people[right].k2 < people[head].k2)
    		{
    			isheap = false;
    			return;
    		}
    		find2(right);
    	}
    }
    
    
    
    int main()
    {
    	for (int i = 0; i < 1001; i++)
    	{
    		ishead[i] = 0;
    	}
    
    	int n;
    	int head = 0;
    	scanf("%d", &n);
    	for (int i = 0; i < n; i++)
    	{
    		people[i].num = i;
    		scanf("%d %d %d %d", &people[i].k1, &people[i].k2, &people[i].left, &people[i].right);
    if(people[i].left!=-1)
    		ishead[people[i].left]=1;
    if (people[i].right != -1)
    		ishead[people[i].right]=1;
    	}
    
    	for (int i = 0; i < n; i++)
    	{
    		if (ishead[i] == 0)
    			head = i;
    	}
    
    	find(head);
    	sort(order1, order1 + n);
    	for (int i = 0; i < n; i++)
    	{
    		if (order1[i] != order2[i])
    			idsearch = false;
    	}
    	if (idsearch == false)
    	{
    		printf("NO
    ");
    	}
    	else
    	{
    		find2(head);
    		if(isheap==false)
    			printf("NO
    ");
    		else
    			printf("YES
    ");
    
    	}
    	
    }
  • 相关阅读:
    HackerRank
    HackerRank
    LeetCode "Kth Smallest Element in a BST"
    HackerRank
    HackerRank
    LeetCode "Roman to Integer"
    LeetCode "Integer to Roman"
    LeetCode "Majority Element II"
    HackerRank
    HackerRank
  • 原文地址:https://www.cnblogs.com/Jason66661010/p/12789007.html
Copyright © 2020-2023  润新知