zoukankan      html  css  js  c++  java
  • pat04-树8. Complete Binary Search Tree (30)

    04-树8. Complete Binary Search Tree (30)

    时间限制
    100 ms
    内存限制
    65536 kB
    代码长度限制
    8000 B
    判题程序
    Standard
    作者
    CHEN, Yue

    A Binary Search Tree (BST) is recursively defined as a binary tree which has the following properties:

    • The left subtree of a node contains only nodes with keys less than the node's key.
    • The right subtree of a node contains only nodes with keys greater than or equal to the node's key.
    • Both the left and right subtrees must also be binary search trees.

    A Complete Binary Tree (CBT) is a tree that is completely filled, with the possible exception of the bottom level, which is filled from left to right.

    Now given a sequence of distinct non-negative integer keys, a unique BST can be constructed if it is required that the tree must also be a CBT. You are supposed to output the level order traversal sequence of this BST.

    Input Specification:

    Each input file contains one test case. For each case, the first line contains a positive integer N (<=1000). Then N distinct non-negative integer keys are given in the next line. All the numbers in a line are separated by a space and are no greater than 2000.

    Output Specification:

    For each test case, print in one line the level order traversal sequence of the corresponding complete binary search tree. All the numbers in a line must be separated by a space, and there must be no extra space at the end of the line.

    Sample Input:
    10
    1 2 3 4 5 6 7 8 9 0
    
    Sample Output:
    6 3 8 1 5 7 9 0 2 4
    

    提交代码

    解法一:

    数组做法:

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<iostream>
     4 #include<cstring>
     5 #include<queue>
     6 #include<vector>
     7 #include<cmath>
     8 #include<string>
     9 using namespace std;
    10 int tree[1005],endtree[1005];
    11 int GetLeftLength(int n){
    12     int h=log(n+1)/log(2);//除去最后一排的元素
    13     int x=n+1-pow(2,h);
    14     if(x>=pow(2,h-1)){
    15         x=pow(2,h-1);
    16     }
    17     return x+pow(2,h-1)-1;
    18 }
    19 void solve(int left,int right,int root){
    20     int n=right-left+1;
    21     if(!n) return;
    22     int l=GetLeftLength(n);
    23     endtree[root]=tree[left+l];
    24     solve(left,left+l-1,root*2+1);
    25     solve(left+l+1,right,root*2+2);
    26 }
    27 int main(){
    28     //freopen("D:\INPUT.txt","r",stdin);
    29     int n;
    30     scanf("%d",&n);
    31     int i;
    32     for(i=0;i<n;i++){
    33         scanf("%d",&tree[i]);
    34     }
    35     sort(tree,tree+n);
    36     solve(0,n-1,0);
    37     printf("%d",endtree[0]);
    38     for(i=1;i<n;i++){
    39         printf(" %d",endtree[i]);
    40     }
    41     printf("
    ");
    42     return 0;
    43 }

    方法二:

    链表做法:

    递归建树的思想:想找出当前的中间大的树,作为当前树根,然后遍历左子树,右子树,最后对所建的BST进行层序遍历。

    当前元素总个数为n,则层数k为ceil(log2(n+1)):

    1.n>=3*2^(k-2),即查找树的最后一个元素位于根的右子树部分。则此时右子树有 n-(3*2^(k-2)-1)+2^(k-2)-1 个元素,左边有 n-右子树元素个数-1=n-(n-(3*2^(k-2)-1)+2^(k-2)-1)-1=2^(k-1)-1个元素,则中间元素下标为 2^(k-1)-1 (从0开始)。

    2.n<3*2^(k-2),即查找树的最后一个元素位于根的左子树部分。则此时右子树有 2^(k-2)-1 个元素,左边有 n-右子树元素个数-1=n-(2^(k-2)-1)-1=n-2^(k-2) 个元素,则中间元素下标为 n-2^(k-2) (从0开始)。

     1 #include<cstdio>
     2 #include<functional>
     3 #include<queue>
     4 #include<cmath>
     5 #include<algorithm>
     6 #include<iostream>
     7 using namespace std;
     8 int mem[1005];
     9 struct node{
    10     int v;
    11     node *l,*r;
    12     node(){
    13         l=r=NULL;
    14     }
    15 };
    16 void CBTBuild(int *mem,int n,int mid,node *&p){
    17     //q.push(mem[mid]);
    18     p=new node();
    19     p->v=mem[mid];
    20     //cout<<mem[mid]<<endl;
    21 
    22     if(mid-1>=0){//left tree
    23         int nn=mid;
    24         int k=ceil(log(nn+1)/log(2));
    25         if(nn>=3*pow(2,k-2)){//超过一半
    26             CBTBuild(mem,nn,pow(2,k-1)-1,p->l);
    27         }
    28         else{//未超过一半
    29             CBTBuild(mem,nn,nn-pow(2,k-2),p->l);
    30         }
    31     }
    32     if(mid+1<n){//right tree
    33         int nn=n-(mid+1);
    34         int k=ceil(log(nn+1)/log(2));
    35         if(nn>=3*pow(2,k-2)){//超过一半
    36             CBTBuild(mem+mid+1,nn,pow(2,k-1)-1,p->r);
    37         }
    38         else{//未超过一半
    39             CBTBuild(mem+mid+1,nn,nn-pow(2,k-2),p->r);
    40         }
    41     }
    42 }
    43 int main(){
    44     //freopen("D:\INPUT.txt","r",stdin);
    45     int n,i,j,k;
    46     queue<node> q;
    47     scanf("%d",&n);
    48     for(i=0;i<n;i++){
    49         scanf("%d",&mem[i]);
    50     }
    51     sort(mem,mem+n);
    52 
    53     /*for(i=0;i<n;i++){
    54         cout<<mem[i]<<endl;
    55     }*/
    56     node *h;
    57     k=ceil(log(n+1)/log(2));
    58     if(n>=3*pow(2,k-2)){//超过一半
    59         CBTBuild(mem,n,pow(2,k-1)-1,h);
    60 
    61         //cout<<mem[int(pow(2,k-1)-1)]<<endl;
    62 
    63     }
    64     else{//未超过一半
    65         CBTBuild(mem,n,n-pow(2,k-2),h);
    66 
    67         //cout<<mem[int(n-pow(2,k-2))]<<endl;
    68 
    69     }
    70     int top;
    71     node p=*h;
    72     q.push(p);
    73     printf("%d",p.v);
    74     while(!q.empty()){
    75         p=q.front();
    76         q.pop();
    77         if(p.l!=NULL){
    78             q.push(*(p.l));
    79             printf(" %d",p.l->v);
    80         }
    81         if(p.r!=NULL){
    82             q.push(*(p.r));
    83             printf(" %d",p.r->v);
    84         }
    85     }
    86     printf("
    ");
    87     return 0;
    88 }
  • 相关阅读:
    Vue的响应式和双向绑定的实现
    JS-跨域请求豆瓣API提供的数据
    豆瓣电影API接口
    JS/PHP-表单文件域上传文件和PHP后台处理
    jQuery-attr,prop及自定义属性
    PHP-关于php代码和html,js混编
    JS-Chrome控制台console.log会访问即时数据
    JS-time和timeEnd
    JS-用ID值直接操作DOM
    CSS-07 行内设置点击事件
  • 原文地址:https://www.cnblogs.com/Deribs4/p/4742026.html
Copyright © 2011-2022 走看看