初次涉及左右值算法(树结构)

1.无限极新增节点

int maxChildRgtVal = orgParent.getRgtVal() - 1; //真理
if (orgParent.getChildNodeCount() != 0) {//如果有子节点,获取子节点最大的右值
    org.setLftVal(maxChildRgtVal + 1);
    org.setRgtVal(maxChildRgtVal + 2);
} else {
    org.setLftVal(orgParent.getLftVal() + 1);
    org.setRgtVal(orgParent.getLftVal() + 2);
}
//更新子节点数
orgDAO.update(orgParent.setChildNodeCount(orgParent.getChildNodeCount() + 1));
//修改右值
orgDAO.updateCus(new CusPara()
        .setStrWhere(String.format(" and rgt_val > %s ", maxChildRgtVal))
        .setStrSet(String.format(" rgt_val=rgt_val + %s", OrgEnum.INIT_RIGHT)));
//修改左值
orgDAO.updateCus(new CusPara()
        .setStrWhere(String.format(" and lft_val > %s ", maxChildRgtVal))
        .setStrSet(String.format("lft_val=lft_val + %s", OrgEnum.INIT_RIGHT)));
 

2.无限极删除节点

//连同子节点一起软删除(修改状态)
cusPara.setStrWhere(
        String.format(" and lft_val >= %s and rgt_val <= %s ", org.getLftVal(), org.getRgtVal()))
        .setStrSet("status = " + DBStatus.DISABLED);
int rs = orgDAO.updateCus(cusPara);
//左右值差值
int lftRgtDiff = param.getRgtVal() - param.getLftVal() + 1;
//重新修改左右值
orgDAO.updateCus(new CusPara()
        .setStrWhere(String.format(" and rgt_val >= %s ", org.getLftVal()))
        .setStrSet(String.format("rgt_val = rgt_val - %s", lftRgtDiff)));
orgDAO.updateCus(new CusPara()
        .setStrWhere(String.format(" and lft_val >= %s ", org.getLftVal()))
        .setStrSet(String.format("lft_val = lft_val - %s", lftRgtDiff)));

3.无限极随意移动节点左右值算法,请各位大神指正,谢谢

  

 public  void changeOrgParent(Org org){

        //当前节点的旧左右值
        Org old_org=orgDAO.getOneById(org.getId());
        int old_rgt=old_org.getRgtVal();
        int old_lft=old_org.getLftVal();
        if(org.getParentId().longValue()==old_org.getParentId().longValue()){
            orgDAO.update(org);
        }else {
            //获取当前节点的子孙节点
            List<Org> sub_list=orgDAO.getCusAll(new CusPara().setStrWhere(String.format(" and lft_val> %s and rgt_val< %s " , old_lft,old_rgt)));
            //获取新父节点
            Org pOrg=orgDAO.getOneById(org.getParentId());
            //新父节点左右值
            int p_rgt=pOrg.getRgtVal();
            int p_lft=pOrg.getLftVal();
            //计算当前节点的新左右值
            int new_lft=p_rgt;
            int new_rgt=old_rgt-(old_lft-new_lft);
            //计算偏移量
            int move=new_rgt-old_rgt;
            //给当前节点赋新的左右值
            org.setRgtVal(new_rgt);
            org.setLftVal(new_lft);
            //检查新的父节点是否是当前节点的子孙节点
            boolean is_sub= sub_list.stream().anyMatch(u ->u.getId().toString().equals(org.getParentId().toString()));
            if(is_sub){
                //获取当前节点原来的父节点
                if(null!=old_org&&null!=old_org.getParentId()){
                    Org old_parent_org=orgDAO.getOneById(old_org.getParentId());
                    //检查旧的父节点的父节点的父节点是否是为 1 的顶级节点,是就不能移动当前节点
                    Org p_p_org=orgDAO.getOneById(old_parent_org.getParentId());
                    if(null!=p_p_org&&p_p_org.getParentId()>1){
                        //新的偏移量算法
                        int new_move=new_rgt-new_lft+1;
                        //所有的右值大于当前节点的旧右值(移动节点的原来右值),左右值加上偏移量
                        int other_l_num=orgDAO.updateCus(new CusPara()
                                .setStrSet(String.format(" rgt_val=rgt_val + %s ,lft_val=lft_val + %s" ,new_move,new_move))
                                .setStrWhere(String.format(" and rgt_val> %s " , old_rgt)));

//                        所有的左值大于当前节点的旧右值,左都加上偏移量
                        CusPara cusPara=new CusPara();
                        cusPara.setStrSet(String.format(" lft_val=lft_val + %s ",new_move));
                        cusPara.setStrWhere(String.format(" and lft_val>%s " , old_rgt));
                        int other_num=orgDAO.updateCus(cusPara);

                        //更新当前节点的新父节点
                        orgDAO.updateCus(new CusPara().setStrSet(String.format("  lft_val= + %s,rgt_val=rgt_val + %s,parent_id= %s",old_lft,new_move,old_org.getParentId()))
                                .setStrWhere(String.format(" and id=%s " , pOrg.getId())));
                        //更新当前节点
                        org.setLftVal(new_lft);
                        org.setRgtVal(new_rgt);
                        orgDAO.update(org);

                        //提取左值大于新父节点的原右值
                        List<Org> list_r=sub_list.stream()
                                .filter(u->u.getLftVal()>p_rgt&&!(u.getId().equals(org.getParentId())))
                                .collect(Collectors.toList());
                        if(list_r.size()>0){
                            //更新子孙节点,左右值都加上偏移量-1
                            String ids=StringUtils.join(list_r.stream().map(Org::getId).collect(Collectors.toList()),",");
                            orgDAO.updateCus(new CusPara()
                                    .setStrSet(String.format(" lft_val=lft_val + %s , rgt_val= rgt_val+ %s " , move-1,move-1))
                                    .setStrWhere(String.format(" and id in(%s)" ,ids)));
                        }
                        //提取右值小于新父节点的原左值
                        List<Org> list_l=sub_list.stream()
                                .filter(u->u.getLftVal()<p_lft&&!(u.getId().equals(org.getParentId())))
                                .collect(Collectors.toList());
                        if(list_l.size()>0){
                            //更新子孙节点,左右值都加上偏移量-1
                            String ids=StringUtils.join(list_l.stream().map(Org::getId).collect(Collectors.toList()),",");
                            orgDAO.updateCus(new CusPara()
                                    .setStrSet(String.format(" lft_val=lft_val + %s , rgt_val= rgt_val+ %s " , move-1,move-1))
                                    .setStrWhere(String.format(" and id in(%s)" ,ids)));
                        }
                        
                    }
                }

            }else {
                //新节点的右值小于当前节点的右值
                if(new_rgt<old_rgt){
                    //更新当前节点
                    int num=orgDAO.update(org);
                    if(num>0){
                        if(sub_list.size()>0){
                            //更新当前节点原来子孙节点
                            int sub_num= orgDAO.updateCus(new CusPara()
                                    .setStrSet(String.format(" lft_val=lft_val + %s , rgt_val=rgt_val + %s " , move,move))
                                    .setStrWhere(String.format(" and lft_val> %s and rgt_val< %s " , old_lft,old_rgt)));
                            if(sub_num>0){

                                //重算偏移量
                                move=new_rgt-new_lft+1;

                                //所有的左值小于新父节点的左值,右值大于新父节点的右值,也就是整条父节点的右值加上偏移量
                                int other_l_num=orgDAO.updateCus(new CusPara()
                                        .setStrSet(String.format(" rgt_val=rgt_val + %s " ,move))
                                        .setStrWhere(String.format(" and rgt_val>= %s and lft_val<= %s" , p_rgt,p_lft)));

                                List<Long> stringList=sub_list.stream().map(Org::getId).collect(Collectors.toList());
                                String ids=StringUtils.join(stringList,",");
                                //所有的左值大于新父节点的右值不包括子孙节点,左右值都加上偏移量
                                CusPara cusPara=new CusPara();
                                cusPara.setStrSet(String.format(" lft_val=lft_val + %s , rgt_val= rgt_val+ %s " , move,move));
                                cusPara.setStrWhere(String.format(" and lft_val>%s and id not in(%s)" , p_rgt,ids));
                                int other_num=orgDAO.updateCus(cusPara);

                            }else {
                                throw new RuntimeException("1014更新子孙节点失败!");
                            }
                        }else {
                            //重算偏移量
                            move=new_rgt-new_lft+1;
                            //所有的左值小于新父节点的左值,右值大于新父节点的右值,也就是整条父节点的右值加上偏移量
                            int other_l_num=orgDAO.updateCus(new CusPara()
                                    .setStrSet(String.format(" rgt_val=rgt_val + %s " ,move))
                                    .setStrWhere(String.format(" and rgt_val >= %s and lft_val<= %s" , p_rgt,p_lft)));


                            List<Long> stringList=sub_list.stream().map(Org::getId).collect(Collectors.toList());
                            String ids=StringUtils.join(stringList,",");
                            //所有的左值大于新父节点的右值,左右值都加上偏移量
                            CusPara cusPara=new CusPara();
                            cusPara.setStrSet(String.format(" lft_val=lft_val + %s , rgt_val= rgt_val+ %s " , move,move));
                            cusPara.setStrWhere(String.format(" and lft_val>%s " , p_rgt,ids));
                            int other_num=orgDAO.updateCus(cusPara);
                        }
                    }else {
                        throw new RuntimeException("1012更新当前节点失败!");
                    }
                }else {

                    //所有的左值大于新父节点的右值,左值都加上偏移量
                    int other_l_num=orgDAO.updateCus(new CusPara()
                            .setStrSet(String.format(" lft_val=lft_val + %s " ,move))
                            .setStrWhere(String.format(" and lft_val> %s" , p_rgt)));
                    //所有的右值大于新父节点的右值,右值都加上偏移量
                    int other_r_num=orgDAO.updateCus(new CusPara()
                            .setStrSet(String.format(" rgt_val=rgt_val + %s " ,move))
                            .setStrWhere(String.format(" and rgt_val>= %s" , p_rgt)));
                    if(other_r_num>0){
                        //更新当前节点
                        int num=orgDAO.update(org);
                        if(num>0){
                            if(sub_list.size()>0){
                                //更新当前节点原来子孙节点
                                int sub_num= orgDAO.updateCus(new CusPara()
                                        .setStrSet(String.format(" lft_val=lft_val + %s , rgt_val=rgt_val + %s " , move,move))
                                        .setStrWhere(String.format(" and lft_val> %s and rgt_val< %s " , old_lft,old_rgt)));
                                if(sub_num<=0){
                                    throw new RuntimeException("1015更新子孙节点失败!");
                                    }
                                }
                            }else {
                                throw new RuntimeException("1017更新当前节点失败!");
                        }
                        }else {
                             throw new RuntimeException("1016更新其它节点失败!");
                    }
                }


            }
        }


    }
原文地址:https://www.cnblogs.com/itliyh/p/12613823.html