PAT甲组1099. Build A Binary Search Tree思路与注意点--补充《算法笔记》

纵饮孤独 提交于 2020-03-01 23:01:26

A1059

题目链接

个人思路

跟A1043出现的问题一样,把问题思考复杂了,上一题还能想到中序遍历的性质,这题却没有想到

  • 构建树,对给出的数据进行升序排序
  • 对每个节点统计其左子树的结点个数numLeft(可以说明该节点前有numLeft节点比当前节点小)
  • 使用hashtable[]标记数据并逐一对节点赋值

个人代码

#include <bits/stdc++.h>
using namespace std;
int N;
int num[105];
bool hashtable[105];
struct Node{
	int data;
	int rchild;
	int lchild;
	Node(){}
	Node(int d, int l, int r)
	{
		data = d;
		lchild = l;
		rchild = r;
	}
}nodes[105];
int numLeft = 0;//记录左子树第一个节点 
void getNumLeft(int root)
{
	numLeft++;
	if(root == -1)//空树 
	{
		numLeft--;
		return;
	}
	if(nodes[root].lchild != -1)
	{
		getNumLeft(nodes[root].lchild);
	}
	if(nodes[root].rchild != -1)
	{
		getNumLeft(nodes[root].rchild);
	}
}
void levelOrder(int root)
{
	int count = 0;
	queue<int> q;
	q.push(root);
	while(!q.empty())
	{
		int now = q.front();
		q.pop();
		count++;
		if(count < N)
			printf("%d ", nodes[now].data);
		else
			printf("%d", nodes[now].data);
		if(nodes[now].lchild != -1)
			q.push(nodes[now].lchild);
		if(nodes[now].rchild != -1)
			q.push(nodes[now].rchild);
	}
}
int main(int argc, char *argv[]) {
	scanf("%d", &N);
	for(int i = 0; i < N; ++i)
	{
		scanf("%d%d", &nodes[i].lchild, &nodes[i].rchild);
	}
	for(int i = 0; i < N; ++i)
	{
		scanf("%d", &num[i]);
	}
	sort(num, num + N);
	for(int i = 0; i < N; ++i)
	{
		numLeft = 0;
		getNumLeft(nodes[i].lchild);
		int cnt = 0;//计数,rank 
		for(int j = 0; j < N; j++)
		{
			if(cnt == numLeft && !hashtable[j])
			{
				nodes[i].data = num[j];
				hashtable[j] = true;//被访问过
				break; 
			}
			if(!hashtable[j])
			{
				cnt++;
			}
		}
	}
	levelOrder(0);
	return 0;
}

本题思路

根据二叉搜索树中序遍历的性质,其中序遍历序列为升序。因此对二叉搜索树中序遍历,对给出数据升序排序,一一对应填入即可。

代码

#include <bits/stdc++.h>
using namespace std;
int N;
int num[105];
vector<int> in;
struct Node{
	int data;
	int rchild;
	int lchild;
	Node(){}
	Node(int d, int l, int r)
	{
		data = d;
		lchild = l;
		rchild = r;
	}
}nodes[105];
void middleOrder(int root)
{
	if(root == -1)
	{
		return;
	}
	middleOrder(nodes[root].lchild);
	in.push_back(root);
	middleOrder(nodes[root].rchild);
}
void levelOrder(int root)
{
	int count = 0;
	queue<int> q;
	q.push(root);
	while(!q.empty())
	{
		int now = q.front();
		q.pop();
		count++;
		if(count < N)
			printf("%d ", nodes[now].data);
		else
			printf("%d", nodes[now].data);
		if(nodes[now].lchild != -1)
			q.push(nodes[now].lchild);
		if(nodes[now].rchild != -1)
			q.push(nodes[now].rchild);
	}
}
int main(int argc, char *argv[]) {
	scanf("%d", &N);
	for(int i = 0; i < N; ++i)
		scanf("%d%d", &nodes[i].lchild, &nodes[i].rchild);
	for(int i = 0; i < N; ++i)
		scanf("%d", &num[i]);
	sort(num, num + N);
	middleOrder(0);
	for(int i = 0; i < in.size(); i++)
	{
		int index = in[i];
		nodes[index].data = num[i];
	}
	levelOrder(0);
	return 0;
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!