问题描述
我正在练习二叉搜索树,我必须回答一个问题: 一个树结构被给出为
struct tree{
int key;
int lcnt;
struct tree *lc;
struct tree *rc;
};
其中 lcnt 是一个整数,保存每个节点左子树的节点数。问题是每次使用有效值的 lcnt 将树分成两半更新。分割算法必须花费 O(h) 时间,其中 h 是树的高度。我在下面找到了解决方案,它适用于大多数树木。但是现在考虑这棵树
170
/
45
\
30
结果将是:tree1: 170,tree2: 45。 我不知道如何修复它,因为如果我尝试诸如“如果节点是叶子则不要拆分”之类的东西,那么我就会遇到其他树的问题。 split 函数采用参数 root ,即主树的根,一个整数,即树的长度/2,并返回 2 棵新树。一个返回,另一个通过引用使用第三个参数双指针树。我还使用 updt 函数和一些计算来在每次拆分时更新 lcnt。
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;
}
这是 updt 函数:
void updt(struct tree* root,int decrease){
struct tree *temp;
temp=root;
while(temp!=NULL){
temp->lcnt=temp->lcnt-decrease;
temp=temp->lc;
}
}
解决方法
您的测试用例,
170
/
45
\
30
不是有效的二叉搜索树。