zoukankan      html  css  js  c++  java
  • 初次涉及左右值算法(树结构)

    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更新其它节点失败!");
                        }
                    }
    
    
                }
            }
    
    
        }
  • 相关阅读:
    Spring@Profile注解
    day 32 子进程的开启 及其用法
    day 31 udp 协议SOCK_DGRAM
    day 30 客户端获取cmd 命令的步骤
    day 29 socket 理论
    day 29 socket 初级版
    有关 组合 继承
    day 27 多态 接口 类方法 静态方法 hashlib 摘要算法模块
    新式类和经典类的区别
    day 28 hasattr getattr serattr delattr 和带__内置__ 类的内置方法
  • 原文地址:https://www.cnblogs.com/itliyh/p/12613823.html
Copyright © 2011-2022 走看看