L3-010 是否完全二叉搜索树 (30分)(搜索二叉树的建立与判断是否是完全二叉树)

L3-010 是否完全二叉搜索树 (30分)

将一系列给定数字顺序插入一个初始为空的二叉搜索树(定义为左子树键值大,右子树键值小),你需要判断最后的树是否一棵完全二叉树,并且给出其层序遍历的结果。

输入格式:
输入第一行给出一个不超过20的正整数N;第二行给出N个互不相同的正整数,其间以空格分隔。

输出格式:
将输入的N个正整数顺序插入一个初始为空的二叉搜索树。在第一行中输出结果树的层序遍历结果,数字间以1个空格分隔,行的首尾不得有多余空格。第二行输出YES,如果该树是完全二叉树;否则输出NO。

输入样例1:
9
38 45 42 24 58 30 67 12 51
输出样例1:
38 45 24 58 42 30 12 67 51
YES
输入样例2:
8
38 24 12 45 58 67 42 51
输出样例2:
38 45 24 58 42 12 67 51
NO

思路:建树后,把树的每一层的值都存下来。保存的时候如果出现一个节点只有1个或者没有子节点的时候存-1,少几个存几个-1,最后只要判断-1是不是都在最后,如果是那么就是完全二叉树,否则就不是。

#include<string.h>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<string>
#include<cstring>
#include<vector>
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 10;
const int inf = 0x3f3f3f3f;
const ll INF = 1ll << 62;
const double PI = acos(-1);
const double eps = 1e-7;
const int mod = 998244353;
#define wait while(1){}
#define speed {ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); }

struct node
{
	int value;
	node *l, *r;
	node(int value = 0, node *l = NULL, node *r = NULL) :value(value), l(l), r(r) {}
};

void buildtree(node *&root, int x)
{
	if (root == NULL)root = new node(x);
	else
	{
		if (x > root->value)buildtree(root->l, x);//大的值往左边插入
		if (x < root->value)buildtree(root->r, x);
	}
}

vector<int>save[25];
void dfs(node *root, int deep)
{
	if (root == NULL)
	{
		save[deep].push_back(-1);
		return;
	}
	save[deep].push_back(root->value);
	dfs(root->l, deep + 1);
	dfs(root->r, deep + 1);
}

void Free(node *root)
{
	if (root == NULL)return;
	Free(root->l);
	Free(root->r);
	delete root;
}

int main()
{
	int n;
	int a[30];//存初始点
	scanf("%d", &n);
	bool res = true;//用来判断是否是完全二叉树
	for (int i = 0; i < n; i++)
		scanf("%d", &a[i]);
	node *root;//建立根节点
	root = new node(a[0]);//给根节点初始化
	for (int i = 1; i < n; i++)//从1开始,0的时候已经被初始化了
		buildtree(root, a[i]);//建树
	dfs(root, 0);//把每一层的节点记录下来,根为层
	int f = 0,flag=0;//f用来保证格式,flag用来判断是否出现过-1,即是否出现过NULL
	for (int i = 0; i <= n; i++)
	{
		for (int j = 0; j < save[i].size(); j++)
		{
			if (save[i][j] != -1)
			{
				if (flag == 1)res = false;//出现过-1然后又出现过不是-1的值说明不是完全二叉树
				if (f == 0) { printf("%d", save[i][j]); f = 1; }
				else printf(" %d", save[i][j]);
			}
			else flag = 1;
		}
	}
	printf("\n");
	Free(root);//释放空间
	if (res)printf("YES\n");
	else printf("NO\n");
	//wait;
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值