蓝桥杯练习 The order of a Tree HDU-3999(二叉树)

The order of a Tree HDU-3999(二叉树)

https://vjudge.net/problem/HDU-3999

HDU-3999
思路:
建立一个二叉排序树,然后输出先序序列
如果单纯用数组做的话,二叉排序树的极端情况是一条链表,空间 2 100000 2^{100000} 2100000,显然会爆掉。所以用链式存储。还可以用三个数组模拟链式结构(好像是叫静态链表)。
求先序序列可以递归做,也可以用栈做(递归就是用栈实现的嘛)。

下面三份代码差别不大,主要区别在于存储结构求先序序列上。
Code1:

//静态链表+递归
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <queue>
#include <cmath>
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const int maxn = 1e5 + 5;

struct Tree
{
	int x, l, r;
	Tree(int x = 0, int l = 0, int r = 0) : x(x), l(l), r(r) {}
} tree[maxn];

void init(int n)
{
	for (int i = 1; i <= n; i++)
	{
		tree[i].x = tree[i].l = tree[i].r = 0;
	}
}

void insertTree(int i)
{
	if (i == 1)
		return;

	int x = tree[i].x, root = 1;
	while (true)
	{
		if (x < tree[root].x)
		{
			if (tree[root].l == 0)
			{
				tree[root].l = i;
				break;
			}
			root = tree[root].l;
		}
		else if (x > tree[root].x)
		{
			if (tree[root].r == 0)
			{
				tree[root].r = i;
				break;
			}
			root = tree[root].r;
		}
	}
}

int cnt;
void preorder(int root = 1)
{
	if (cnt++)
		printf(" ");
	printf("%d", tree[root].x);
	if (tree[root].l != 0)
		preorder(tree[root].l);
	if (tree[root].r != 0)
		preorder(tree[root].r);
}

int main()
{
	int n, x;
	while (scanf("%d", &n) != EOF)
	{
		init(n);
		for (int i = 1; i <= n; i++)
		{
			scanf("%d", &tree[i].x);
			insertTree(i);
		}
		cnt = 0;
		preorder();
		printf("\n");
	}
	return 0;
}

Code2:

//静态链表+栈
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <queue>
#include <stack>
#include <cmath>
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const int maxn = 1e5 + 5;

struct Tree
{
	int x, l, r;
	Tree(int x = 0, int l = 0, int r = 0) : x(x), l(l), r(r) {}
} tree[maxn];

void init(int n)
{
	for (int i = 1; i <= n; i++)
	{
		tree[i].x = 0;
		tree[i].l = 0;
		tree[i].r = 0;
	}
}

void insertTree(int i)
{
	if (i == 1)
		return;

	int x = tree[i].x, root = 1;
	while (true)
	{
		if (x < tree[root].x)
		{
			if (tree[root].l == 0)
			{
				tree[root].l = i;
				return;
			}
			root = tree[root].l;
		}
		else if (x > tree[root].x)
		{
			if (tree[root].r == 0)
			{
				tree[root].r = i;
				return;
			}
			root = tree[root].r;
		}
	}
}

void preorder()
{
	int root = 1, cnt = 0;
	stack<int> s;
	s.push(root);
	while (!s.empty())
	{
		root = s.top();
		s.pop();
		if (cnt++)
			printf(" ");
		printf("%d", tree[root].x);
		if (tree[root].r)
			s.push(tree[root].r);
		if (tree[root].l)
			s.push(tree[root].l);
	}
	printf("\n");
}

int main()
{
	int n, x;
	while (scanf("%d", &n) != EOF)
	{
		init(n);
		for (int i = 1; i <= n; i++)
		{
			scanf("%d", &tree[i].x);
			insertTree(i);
		}
		preorder();
	}
	return 0;
}

Code3:

//链式存储+栈
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <stack>
using namespace std;

struct node
{
	int x;
	node *l, *r;
};

node *head;

void insertTree(node *k)
{
	node *root;
	root = head;
	if (head == NULL)
	{
		head = k;
	}
	else
	{
		while (true)
		{
			if (root->x > k->x)
			{
				if (root->l)
				{
					root = root->l;
				}
				else
				{
					root->l = k;
					return;
				}
			}
			else
			{
				if (root->r)
				{
					root = root->r;
				}
				else
				{
					root->r = k;
					return;
				}
			}
		}
	}
}

void preorder()
{
	stack<node *> s;
	node *root = head;
	int cnt = 0;
	s.push(root);
	while (!s.empty())
	{
		root = s.top();
		if (cnt++)
			printf(" ");
		printf("%d", root->x);
		s.pop();
		if (root->r)
			s.push(root->r);
		if (root->l)
			s.push(root->l);
		free(root);
	}
	printf("\n");
}

int main()
{
	int n, x;
	while (scanf("%d", &n) != EOF)
	{
		node *f;
		head = NULL;
		for (int i = 0; i < n; i++)
		{
			scanf("%d", &x);
			f = (node *)malloc(sizeof(node));
			f->x = x;
			f->l = f->r = NULL;
			insertTree(f);
		}
		preorder();
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值