The order of a Tree 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;
}