03-树3 Tree Traversals Again
分数 25
作者 陈越
单位 浙江大学
An inorder binary tree traversal can be implemented in a non-recursive way with a stack. For example, suppose that when a 6-node binary tree (with the keys numbered from 1 to 6) is traversed, the stack operations are: push(1); push(2); push(3); pop(); pop(); push(4); pop(); pop(); push(5); push(6); pop(); pop(). Then a unique binary tree (shown in Figure 1) can be generated from this sequence of operations. Your task is to give the postorder traversal sequence of this tree.
Figure 1
Input Specification:
Each input file contains one test case. For each case, the first line contains a positive integer N (≤30) which is the total number of nodes in a tree (and hence the nodes are numbered from 1 to N). Then 2N lines follow, each describes a stack operation in the format: "Push X" where X is the index of the node being pushed onto the stack; or "Pop" meaning to pop one node from the stack.
Output Specification:
For each test case, print the postorder traversal sequence of the corresponding tree in one line. A solution is guaranteed to exist. All the numbers must be separated by exactly one space, and there must be no extra space at the end of the line.
Sample Input:
6
Push 1
Push 2
Push 3
Pop
Pop
Push 4
Pop
Pop
Push 5
Push 6
Pop
Pop
Sample Output:
3 4 2 6 5 1
建立一棵完全二叉搜索树,用指针实现:
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
typedef struct TNode* Bin;
struct TNode
{
int v;
Bin l, r;
};
const int N = 1010;
int a[N];
int flag = 1;
Bin NewNode(int v)
{
Bin t = new TNode;
t->v = v;
t->l = t->r = NULL;
return t;
}
Bin insert(int num, int l, int r)
{
//h是num个结点能构成完全二叉树的层数先下取整,sum是构成满二叉树的节点数
int h = 1, sum = 0;
while(sum+h <= num)
{
sum += h;
h += h;
}
//rest为最后一层不是满二叉树的节点数量
int rest = num - sum;
//左子树的节点数量
int lnum = min(rest, h/2) + sum/2;
//右子树的节点数量
int rnum = max(0, rest - h/2) + sum/2;
Bin t = NULL;
t = NewNode(a[l + lnum]);
if(lnum >= 1) //如果左子树有节点
t->l = insert(lnum, l, l+lnum-1);
if(rnum >= 1) //如果右子树有节点
t->r = insert(rnum, l+lnum+1, r);
return t;
}
void lay_traver(Bin root)
{
queue<Bin> q;
q.push(root);
while(q.size())
{
Bin u = q.front();
q.pop();
if(flag)
flag = 0;
else
cout << ' ';
cout << u->v;
if(u->l)
q.push(u->l);
if(u->r)
q.push(u->r);
}
}
int main()
{
int n;
cin >> n;
for(int i=0; i<n; ++i)
cin >> a[i];
sort(a, a+n);
Bin root = NULL;
root = insert(n, 0, n-1);
lay_traver(root);
return 0;
}
一棵树建立为完全二叉搜索树,数组实现,浙大数据结构代码:
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
const int maxn=2010;
int a[maxn],lev[maxn];
void solve(int index,int l,int r); //将原数组合适的位置的值填到 lev[index] 数组里
int main()
{
int n;
cin >> n;
for(int i=1;i<=n;++i)
cin >> a[i];
sort(a+1,a+n+1); //将原数组排好序
solve(1,1,n);
for(int i=1;i<=n;++i)
{
if(i!=1)
cout << ' ';
cout << lev[i];
}
return 0;
}
void solve(int index,int l,int r) //将原数组合适的位置的值填到 lev[index] 数组里
{
if(l>r) //如果区间内没有元素就返回
return ;
if(l==r) //如果区间内只有一个元素
{
lev[index]=a[l];
return;
}
int sum=r-l+1;
int H=log(sum+1) / log(2); // H=floor( log2(sum+1))
int numL;
int rest=sum-(int)pow(2,H)+1; //计算最后一排的节点数
if(rest <= (int)pow(2,H-1) ) //如果最后一排的节点数完全在左子树上
numL=(int)pow(2,H-1) - 1 + rest; //那么就可以把rest的结点数加到numL上
else
numL=(int)pow(2,H-1) - 1 +(int)pow(2,H-1); //否则只能加pow(2,H-1);
lev[index]=a[l+numL];
solve(2*index,l,l+numL-1); //递归左子树
solve(2*index+1,l+numL+1,r); //递归右子树
}