1064 Complete Binary Search Tree (构建完全二叉搜索树)

题目大意:给定一些结点,构建完全二叉搜索树。

(注意完全二叉树不是满二叉树,而是一层一层从左往右叠满的,所以最后一层可能有空的位置。)

思路:我们知道二叉搜索树的中序遍历即为每个结点的从小到大排序,故我们可以先将结点排序,于是我们就得到了这课二叉树的中序遍历,于是问题就转化成了:已知中序遍历,求满二叉搜索树。我们要想使用中序遍历构建二叉树,关键点在于找到树(子树)的根结点,剩下的就好说了。那么满二叉树的根结点有什么规律呢?

首先,我们考虑满二叉树,结点数为:2^n-1(n为层数),那么如果我们将完全二叉树补满,则需要的结点数设为sub,sub可求,那么我们可以知道完全二叉树的最后一层结点的分布情况。将最后一层的结点分成所属左右子树两部分,则左子树的整棵树结点数可以求出设为num,则在中序遍历中前面的num个结点都所属左子树,则第num+1个结点就是根结点,然后以此类推,写一个递归就行了。

简而言之就是:已知完全二叉树的结点数,求左子树的结点数num,则根为第num+1个结点。

#include
using namespace std;
struct node{
    int val;
    node* l;
    node* r;
    node(int x):val(x){}
};
int n;
int p[1010];
int fill(int x){
    x++;
    int k=log(x)/log(2);
    if(pow(2,k)==x)return x-1;
    else return pow(2,k+1)-1;
}
int bottom(int x){
    int k=log(fill(x)+1)/log(2)-1;
    return pow(2,k);
}
node* create(int l,int r){
    if(l>r)return nullptr;
    int len=r-l+1;
    int sub=fill(len)-len;
    int leaf=bottom(len)-sub;
    int pos;
    if(leaf>=sub){
        pos=l+fill(len)/2;
    }else{
        pos=l+fill(len)/2-(bottom(len)/2-leaf);
    }
    node *nod=new node(p[pos]);
    nod->l=create(l,pos-1);
    nod->r=create(pos+1,r);
    return nod;
}
int flag=0;
void leverorder(node* nod){
    queueq;
    q.push(nod);
    while(q.size()){
        int len=q.size();
        while(len--){
            node* f=q.front();
            q.pop();
            if(flag)cout<<' ';
            cout<val;flag=1;
            if(f->l)
                q.push(f->l);
            if(f->r)
                q.push(f->r);
        }
    }
}
int main(){
    cin>>n;
    for(int i=0;i>p[i];
    sort(p,p+n);
    node* root=create(0,n-1);
    leverorder(root);
}

你可能感兴趣的:(数据结构,算法)