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更新其它节点失败!");
                        }
                    }
    
    
                }
            }
    
    
        }
  • 相关阅读:
    [摘]提高SQL语句查询效率的若干建议
    WinForm做的一个多条件查询,主要是解决多控件联动
    MSCRM中用IFRAME显示实体的关联视图
    windows 常用命令
    mscrm WebService开发 之 CrmDiscoveryService
    Mscrm 二次开发之 plugin开发
    热血高校2
    6、情人节杀人事件
    热血高校
    第八章 培养幽默的习惯
  • 原文地址:https://www.cnblogs.com/itliyh/p/12613823.html
Copyright © 2011-2022 走看看