我在写一个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、一种叫“完全二分法“吧,第一个节点用中间数值‘HHH’,下一个节点生成时如果在前插入则取当前节点和前一个节点的中间值,在后添加则取当前节点和最后节点(‘ZZZ’)的中间值。此方法对插入比较好,但一般情况下使用只是按顺序向后添加,这样的话如果每级节点长度为3则最多只能向后添加15个节点(2的15次方 < 36*36*36 < 2的16次方)。
2、另一种叫“插入二分法”吧,设置一个添加间隔(比如50个),则添加时第一个节点为‘01D’,第二个节点为‘03Q’,插入时采用二分法为当前节点和前一节点中间值。
此方法添加比较好,偶尔插入几个也行,但一次不能在同一节点前插入太多。 说了太多,忘各位高手提供一个算法,不要太复杂哦。
分不够可以加,别的没有就是分多,哈哈
下级的代码为下级的代码加上两位下级代码。
这样增加、删除、修改都没有什么问题。
而且可以使用Dev Express套件里面的dxdbtreeview。
非常好用的。
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';