我在写一个DBTree的程序,树由数据库生成,有两个字段Code和UpCode,Code是节点代码,UpCode是父节点代码。Code和UpCode为字符型,由一序列(0……9ABC……Z)生成(相当于36进制),每级节点有统一长度。开始时的思路是节点由‘0’开始,然后下一个节点递增1。比如如果级节点宽度为3,则第一个节点为‘000’,下一个为‘001’,最后为‘ZZZ’。
    这种方法比较简单容易实现,但灵活性太差,生成后不能再中间插入节点。如果插入移动后面节点的话,数据操作太多效率可能很差。我想到两种改进节点生成的算法,但发觉都不是太好。    1、一种叫“完全二分法“吧,第一个节点用中间数值‘HHH’,下一个节点生成时如果在前插入则取当前节点和前一个节点的中间值,在后添加则取当前节点和最后节点(‘ZZZ’)的中间值。此方法对插入比较好,但一般情况下使用只是按顺序向后添加,这样的话如果每级节点长度为3则最多只能向后添加15个节点(2的15次方 < 36*36*36 < 2的16次方)。
 
    2、另一种叫“插入二分法”吧,设置一个添加间隔(比如50个),则添加时第一个节点为‘01D’,第二个节点为‘03Q’,插入时采用二分法为当前节点和前一节点中间值。
此方法添加比较好,偶尔插入几个也行,但一次不能在同一节点前插入太多。    说了太多,忘各位高手提供一个算法,不要太复杂哦。
  
    分不够可以加,别的没有就是分多,哈哈

解决方案 »

  1.   

    我觉得你可以借鉴财务软件里面的科目树分级方法。
    下级的代码为下级的代码加上两位下级代码。
    这样增加、删除、修改都没有什么问题。
    而且可以使用Dev Express套件里面的dxdbtreeview。
    非常好用的。
      

  2.   

    flyingkiller(大飞虫) “下级的代码为下级的代码加上两位下级代码。” 什么意思
      

  3.   

    給一個字符串序號加1的函數你:
      function fGetID(const strID:string):string;
      var
        strRslt:string;
        prChrA:char;
        prPChr:PChar;
        arCHR:array of char;
        arNum:array of shortint;
        nLen,idxi,nSerial,nCarry,nBit:integer;
        
      begin
        if strID='' then
        begin
          result:='';
          exit;
        end;
        strRslt:=strid;
        //if is numeric:
        val(strRslt,idxi,nCarry);
        if nCarry=0 then
        begin
            inc(idxi);
            strRslt:=inttostr(idxi);
            nLen:=Length(strId);
            nSerial:=Length(strRslt);
            fGetID:=StringOfChar('0',nLen-nSerial)+strRslt;
            Exit;
        end;
        nSerial:=0;
        nLen:=Length(strRslt);
        SetLength(arCHR,nLen+1);
        SetLength(arNum,nLen+1);
        prPChr:=PChar(strRslt);
        for idxi:=0 to nLen-1 do
        begin
            prChrA:=prPChr[idxi]; 
            arCHR[idxi]:=prChrA;
            if ord(prChrA)>ord('9') then
            begin
                arCHR[idxi]:=prChrA;
                arNum[idxi]:=-1;
                nSerial:=0;
            end
            else if ord(prChrA)>=ord('0') then
            begin
                
                arNum[idxi]:=Ord(prChrA)-ord('0');
                nSerial:=nSerial+1;
            end else
            begin
                
                arNum[idxi]:=0;
                nSerial:=nSerial+1;
            end;
        end;
        nCarry:=1;
        for idxi:=nLen-1 downto 0 do
        begin
            
            
            if nSerial>0 then
            begin
                nBit:=arNum[idxi]+nCarry;
                nCarry:=0;
                if nBit>9 then
                begin
                    nbit:=nBit-10;
                    nCarry:=1;
                end;
                arCHR[idxi]:=Chr(Ord('0')+nBit);
                nSerial:=nSerial-1;
                
            end
            else
            begin
                arCHR[idxi]:=Chr(ord(arCHR[idxi])+nCarry);
                if arCHR[idxi]>'Z' then
                    begin
                        arCHR[idxi]:='A';
                        nCarry:=1;
                    end
                else
                    begin
                        nCarry:=0;
                    end;
            end;
        end;
        if nCarry>0 then
        begin
            
            SetLength(arCHR,nLen+2);
            prPChr[0]:='A';
            for idxi:=0 to nLen-1 do
            begin
                prPChr[idxi+1]:=arCHR[idxi];
            end;
        end
        else
        begin
            for idxi:=0 to nLen-1 do
            begin
                prPChr[idxi]:=arCHR[idxi];
            end;
        end;
        strRslt:=string(prPChr);
        fGetID:=(strRslt);
      end;
       結果:
      fGetID('AAAB')='AAAC';
      fGetID('A002')='A003';
      fGetID('0000')='0001';