1110 Complete Binary Tree(25分)

题目翻译:

给定一颗树,判断其是否为完全二叉树。

题解思路:

思路一(层序遍历):

在层序遍历过程中,有三种情况可供判断是不是完全二叉树:

  • 遇到“无左孩子,有右孩子”的情况,有这种情况可以直接认定为非完全二叉树。
  • 遇到”无孩子“的情况,则接下来的节点都不能有孩子,否则是非完全二叉树。
  • 遇到“左空右不空”的情况,则接下来的节点都不能有孩子,否则是非完全二叉树。

思路二(DFS):

 可以看出方法一的判断有一点麻烦。由于完全二叉树他的编号与满二叉树一一对应,所以可以直接DFS搜索,然后看每一个结点位置是否都小于N就好了,因为一旦有结点位置不小于N,就与满二叉树无法对应了。转载于1110解法

代码:

思路一:

#include
using namespace std;
int N;
struct node {
	int left = -1, right = -1;
};
vector v(21);

void level_order(int root)
{
	queue p;
	int last;
	bool tag = 0;//1表示找到了不饱和点
	p.push(root);
	while (p.size())
	{
		last = p.back();
		int curfront = p.front();
		if (tag)//找到了不饱和点
		{
			if (v[curfront].left != -1 || v[curfront].right != -1)
			{
				cout << "NO" << " " << root;
				return;
			}
			else
				p.pop();
		}
		else
		{
			if (v[curfront].left == -1 && v[curfront].right != -1)//左空右不空,一定不是二叉树
			{
				cout << "NO" << " " << root;
				return;
			}
			else if (v[curfront].left != -1 && v[curfront].right != -1)//左右都不为空,继续往下遍历
			{
				p.pop();
				p.push(v[curfront].left);
				p.push(v[curfront].right);
			}
			else if (v[curfront].left != -1 && v[curfront].right == -1)//后边的必须全都没有孩子结点
			{
				p.pop();
				p.push(v[curfront].left);
				tag = 1;
			}
			else if (v[curfront].left == -1 && v[curfront].right == -1)//遇到叶子结点,后续的必须全为空
			{
				p.pop();
				tag = 1;
			}
		}
	}
	cout << "YES" << " " << last;
}

int main()
{
	cin >> N;
	int root = N * (N - 1) / 2;
	for (int i = 0;i < N;i++)
	{
		for (int j = 0;j < 2;j++)
		{
			char a[3];
			int b;
			cin >> a;
			if (a[0]=='-')
				continue;
			else
			{
				sscanf(a, "%d", &b);
				root -= b;
				if (j == 0)
					v[i].left = b;
				else
					v[i].right = b;
			}
		}
	}
	level_order(root);
}

思路二:

#include
using namespace std;

int N;
vector> tree;
vector have_parent;
int root_node, last_node, max_pos;

void init() {
	cin >> N;
	tree.resize(N);
	have_parent.resize(N, 0);
	for (int i = 0; i < N; ++i) {
		string l, r;
		cin >> l >> r;
		if (l == "-") {
			tree[i].first = -1;
		}
		else {
			tree[i].first = stoi(l);
			have_parent[stoi(l)] = 1;
		}
		if (r == "-") {
			tree[i].second = -1;
		}
		else {
			tree[i].second = stoi(r);
			have_parent[stoi(r)] = 1;
		}
	}
	for (int i = 0; i < N; ++i) {
		if (have_parent[i] == 0) {
			root_node = i;
			return;
		}
	}
}

//查找最大位置
void dfs(int root, int pos) {//当前结点编号,当前搜索位置
	if (pos > max_pos) {
		max_pos = pos;
		last_node = root;
	}
	if (tree[root].first != -1) {
		dfs(tree[root].first, pos * 2 + 1);
	}
	if (tree[root].second != -1) {
		dfs(tree[root].second, pos * 2 + 2);
	}
}

int main() {
	init();
	dfs(root_node, 0);
	if (max_pos < N) {
		cout << "YES " << last_node << endl;
	}
	else {
		cout << "NO " << root_node << endl;
	}
	return 0;
}

坑点:

你可能感兴趣的:(算法,数据结构)