ural(Timus) 1136. Parliament
数据结构--二叉查找树遍历
题意:n,表示二叉查找树的节点个数,每个节点有个数值,并且数值各异不会出现重复的,查找树左子树的节点数值小于根,右子树的节点数值大于根。
一般的后序遍历二叉树时 左孩子,右孩子,根 ; 现在定义一种新的后序遍历 右孩子,左孩子,根
输入n,下面一个序列,是普通后序遍历二叉树的序列 , 要你根据这个序列,输出新定义的那种后序遍历序列
讲到这里,看图,看sample可以理解题意了
要是一般的二叉树只知道后序遍历序列是不能建树的,但是这里是二叉查找树却可以
对于一个后序遍历序列,它可以分解为 (左子树部分)(右子树部分)(根),由于是查找树,可知(左子树)<(根) (右子树)>(根)
所以对于当前一个区间内的序列[l,r],可以知道r下标对应的数值一定是当前子树的根,然后找到一个下标k, [l,k-1] 里面的数值都小于根,他们是左子树 , [k,r-1]里面的数值都大于根,他们是右子树,这样就可以递归建树下去了。建树之后直接用新的规则后序遍历二叉树即可
简单题1A
#include <cstdio> #include <cstring> #define N 3010 int a[N],tot; struct node { int n; int lch,rch; }t[N]; int n; int build(int l ,int r) { if(l > r) return -1; int i,pos; t[tot].n = a[r]; //保存树根 pos = tot++; if(l == r) return pos; for(i=l; i<r; i++) if(a[i] > a[r]) break; //左子树区间[l,i-1] , 右子树区间[i,r-1] int lch = build(l,i-1); int rch = build(i,r-1); t[pos].lch = lch; t[pos].rch = rch; return pos; } void Travel(int rt) { if(rt == -1) return ; Travel(t[rt].rch); Travel(t[rt].lch); if(rt == 0) printf("%d\n",t[rt].n); else printf("%d ",t[rt].n); } int main() { while(scanf("%d",&n)!=EOF) { memset(t,-1,sizeof(t)); for(int i=0; i<n; i++) scanf("%d",&a[i]); tot=0; build(0,n-1); //递归建树 Travel(0); } return 0; }