Codeup Problem B: 二叉搜索树

原题地址

http://codeup.hustoj.com/problem.php?cid=100000613&pid=1

解题思路

基本和上一篇方法一样~

注意事项

读入数据的时候注意按照字符串读进来,我一开始直接按照数字读,然后就相当于一行只读进来了一个数字~

参考代码

#include <bits/stdc++.h>
using namespace std;
#define pb push_back
typedef double db;
typedef long long LL;
typedef vector<int> VI;
const int inf = 2e9;
const LL INF = 8e18;
const int maxn = 5e5 + 5;
string s;

struct node{
	int data;
	node* lchild;
	node* rchild;
	int flag;  //标记结点是否访问过,访问过为1 
};

//这里要改变指针变量,所以要用引用!! 
void insert(node* &root, int v) {
	if (!root) {
		root = new node;
		root->data = v;
		root->flag = 0;
		root->lchild = root->rchild = NULL;
		return;
	}
	if (v == root->data) return;
	if (v < root->data) insert(root->lchild, v);
	else insert(root->rchild, v);
}

node* create(int n) {
	node* root = NULL;
	int i, v;
	for (i = 0; i < n; ++i) {
		insert(root, s[i] - '0');
	}
	return root;
}

/*
判别方法:
转化为查找待判断序列中的数
若查找某个数的过程中,路径上的数有未访问过的,则不一致
否则一致
*/
int check(node* t, int v) {
	//若该结点是访问过的 
	if (t->flag) {
		if (v < t->data) return check(t->lchild, v);
		else if (v > t->data) return check(t->rchild, v);
		//若有重复值,代表不一致 
		else return 0;
	}
	//若该结点还未访问过 
	else {
		//正好是要查找的结点 
		if (v == t->data) {
			t->flag = 1;
			return 1;
		}
		//若遇到未访问过的结点,又不是要查找的,则代表不一致 
		else return 0; 
	}
}

//判别每个元素是否一致
int judge(node* t, int n) {
	int i, v;
	bool flag = true;
	
	cin >> s;	
	//先判断树根是否一致
	if (s[0] - '0' != t->data) flag = false;
	else t->flag = 1;
	for (i = 1; i < n; ++i) {
		if (flag && (!check(t, s[i] - '0'))) flag = false;
	} 
	if (flag) return 1;
	else return 0;
} 

//清除t中各结点的flag标记 
void reset(node* t) {
	if (t->lchild) reset(t->lchild);
	if (t->rchild) reset(t->rchild);
	t->flag = 0;
}

//释放t的空间
void freeT(node* t) {
	if (t->lchild) freeT(t->lchild);
	if (t->rchild) freeT(t->rchild);
	delete t;
} 
int main() {
	int n, k;
	while (~scanf("%d", &k)) {
		if (k == 0) break;
		cin >> s;
		n = s.size();
		node* t = create(n);
		while (k--) {
			if (judge(t, n)) printf("YES\n");
			else printf("NO\n");
			reset(t);
		}
		freeT(t);
	}
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值