简体   繁体   English

在 O(h) 时间复杂度内将二叉搜索树一分为二

[英]spliting a binary search tree in half in O(h) time complexity

I am practicing binary search trees and i have to answer a problem: A tree struct is given as我正在练习二叉搜索树,我必须回答一个问题:树结构为

struct tree{
    int key;
    int lcnt;
    struct tree *lc;
    struct tree *rc;
};

where lcnt is an integer holding the number of the nodes at the left subtree of each node.其中 lcnt 是一个 integer ,其中包含每个节点左子树上的节点数。 The problem is to split the tree in half updating every time the lcnt with the valid value.问题是每次更新具有有效值的 lcnt 时将树分成两半。 The split algorith must take O(h) time where h is the tree's hight.拆分算法必须花费 O(h) 时间,其中 h 是树的高度。 I found the solution down below and it works for the most trees.我在下面找到了解决方案,它适用于大多数树木。 But consider now this tree但是现在考虑这棵树

          170
         /
       45
        \
         30

the result will be: tree1: 170, tree2: 45. I have no idea how to fix it because if i try something like "dont split if the node is a leaf" or something then i have problems with other trees.结果将是:tree1:170,tree2:45。我不知道如何解决它,因为如果我尝试“如果节点是叶子,则不要分裂”之类的东西,那么我会遇到其他树的问题。 The split function takes the parameter root which is the root of the primary tree, an integer which is the trees lenght/2 and it returns the 2 new trees.拆分 function 采用参数 root 是主树的根,一个 integer 是树的长度/2,它返回 2 个新树。 The one with return and the other by reference using a third parameter double pointer tree.一个返回,另一个通过引用使用第三个参数双指针树。 I am also using updt function and some calculations to update the lcnt at every split.我还使用 updt function 和一些计算来在每次拆分时更新 lcnt。

the code is here:代码在这里:

struct tree* split(struct tree *root, struct tree **new_tree, int collect){
     struct tree *new_root_1, *new_root_2, *link1=NULL, *link2=NULL;
     struct tree *current=root, *prev=NULL, *temp=NULL;
     if(!root)
         return NULL; //empty tree
     int collected=0, created_root1=0, created_root2=0;
     int decrease;
     while(current!=NULL && collected<collect){
         if(collected+current->lcnt+1<=collect){
             // there is space for the left subtree so take it all and move to the right
             collected=collected+current->lcnt+1;  //update the number of the collected nodes
             if(!created_root1){
                 //create the root for the one tree
                 created_root1=1;
                 new_root_1=current;
                 link1=current;
             }else{
                 link1->rc=current;
                 link1=current;
             }
             if(!created_root2 && collect==collected)
                 //in case the tree must be splited in half
                 new_root_2=current->rc;
             prev=current;
             current=current->rc;
             //break the node link
             prev->rc=NULL;
         }else{
             // there is no space for the left subtree so traverse it until it becomes small enough
             if(!created_root2){
                 //create the root for the second tree
                 created_root2=1;
                 new_root_2=current;
                 link2=current;
             }else{
                 link2->lc=current;
                 // at every link at left the count_total_tasks will help to update the lcnt of the 
                 parent node
                 temp=new_root_2;
                 while(temp!=NULL){
                     temp->lcnt=count_total_tasks(temp->lc);
                     temp=temp->lc;
                 }
                 
                 link2=current;
             }
             prev=current;
             current=current->lc;
 
             //break the node link
             prev->lc=NULL;
             //update the lcnt
             decrease=prev->lcnt;
             updt(new_root_2, decrease);         
         }
     }
     *new_tree=new_root_2;
 
     return new_root_1; 
 }

And this is the updt function:这是升级版 function:

void updt(struct tree* root, int decrease){
    struct tree *temp;
    temp=root;
    while(temp!=NULL){
    temp->lcnt=temp->lcnt-decrease;
        temp=temp->lc;
    }
}

Your test case,你的测试用例,

     170
     /
   45
    \
     30

is not a valid binary search tree.不是有效的二叉搜索树。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM