⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 使用多中值排序基数实现大型树状结构.txt

📁 用纯ASP代码实现图片上传并存入数据库中
💻 TXT
📖 第 1 页 / 共 2 页
字号:
            end select
          END
        INSERT into forum (rootid,deep,ordernum,orderS……) values(@rootid,@deep+1,@ordernum,@ordernumS……)
       END
    END
  Select @message='成功'
  return



剪枝存储过程:
CREATE PROCEDURE [del] @keyid int,@message varchar(50) OUTPUT  ———keyid为要删除的贴子id号,如果是新贴则为0,@message为出错信息
AS
DECLARE @rootid int,@id int,@deep int,@deept int
SELECT @rootid=0,@id=0,@deep=0,@deept=0
SELECT @id=id,@rootid=rootid,@deept=deep from forum where id=@keyid
IF (@id=0)
  BEGIN
   SELECT @message='该贴子不存在!"
   return
  END
ELSE
  BEGIN
    if (@rootid=0)   ——要删的是根贴
      delete from forum where id=@id or rootid=@id
    else    ——剪子枝
      BEGIN
        DECLARE forum_cur CURSOR
         FOR
          SELECT deep FROM forum WHERE rootid=@rootid and (ordernum>@ordernum or ordernum=@ordernum and ordernumS>=@ordernumS) order by ordernum,ordernumS
        OPEN forum_cur
        FETCH FROM forum_cur INTO @deep
        DELETE FROM forum where CURRENT OF forum_cur  ——删除最顶枝
        WHILE @@fetch_status=0
          BEGIN
            FETCH FROM forum_cur INTO @deep
            IF (@deep<=@tdeep) or @@fetch_status<>0  ——一旦发现深比枝顶的深相等或还要小或者游标到了尾部,则马上退出
              BEGIN
                select @message='成功删除子枝'
                CLOSE forum_cur
                DEALLOCATE forum_cur
                return
              END
            DELETE FROM forum WHERE CURRENT OF forum_cur
          END
        END
        CLOSE freelt_cur
        DEALLOCATE forum_cur
      END
  END

显示(略)


    过程看起来比使用单个排序基数复杂了不少,其实主要是判断何时给第二基数赋值的问题。
    注意事项:基数起始值不能取类型的最大值,比如int的最大限制为2^31,则基数起始值要预留空间,否则最后的子贴是无法回复的!!(或者如果限制了ordernum的范围,虽然可以回复,但它是平行显示的)
    使用了两个基数的时候,一个子贴的回复数最多了900左右(int类型,30*30),14400(使用numeric类型时——此时的精度标记得细加斟酌),理论是有限制都是不够的,但实际上并不需要这么多。
    对于基数分布不均匀的问题是无法解决的,因为实际上回复客户回复哪条贴子是不可预测的。
    使用2的幂作为基数,是很容易理解的——不易近起结果取近似值(除非达到了计算机的最大精度),另一个原因是计算机使用二进制进行运算,乘除2只是位移操作,速度要比其它数快得多(我是这么想的)。另一个个人的原因是因为我个算法是源于以前的思想:收敛数列与递归算法。
    由于增加了算法复杂程度和冗余字段,如非必要,实非不必。
    其实我是没有时间进行测试的,如果由于考虑不周或者算法错误引起无法使用,还请多多指教。
    
欢迎访问我的个人主页http://swuse.yeah.net




“中值排序基数法实现树状结构”的补充    


--------------------------------------------------------------------------------

 【廖家远】 于 2000-07-29 15:09:51 加贴在 Joy ASP ↑:

“中值排序基数法实现树状结构”的补充

    由于一时疏忽,造成了此法“对于int类型的基数字段,对原始贴的回复只能有31个;numeric类型的基数字段,对原始贴的回复也不能超过120个”(实际上是对于int型字段,原始贴的回复第32个以上的树状结构显示开始紊乱,对于numeric型的基数字段,原始贴的回复从121个以上树状结构显示开始紊乱——回复并不会出问题),这是由于计算机存储精度引起的。
    我们可以将加贴的存储过程修改一下(加进前面加上**号的行)以限制到了一定深度(在特定数据类型下,基数无法分辨)的时候不再以树状结构显示(而采用平显——平行显示,这样做虽然有点象折衷的做法,但在实际上由于浏览器等的限制——即使在深度100的时候能以树状结构显示,但从你的浏览器看来的树状结构的结果仍然不是清晰的——屏幕宽度不够,会折行呗)。

加贴存储过程:

CREATE PROCEDURE [add] @keyid int,@message varchar(50) OUTPUT  ———keyid为回复的贴子id号,如果是新贴则为0,@message为出错信息
AS
  IF (@keyid=0)
    INSERT INTO forum (rootid,deep,ordernum,……) values(0,0,0,……)
  ELSE
    BEGIN
     DECLARE @rootid int,@id int,@deep int,@begnum float,@endnum float,@ordernum float
     SELECT @rootid=0,@id=0,@deep=0,@begnum=0,@endnum=0,@ordernum=0
     SELECT @rootid=rootid,@id=id,@begnum=ordernum,@deep=deep from forum where id=@keyid
     IF (@id=0)
       BEGIN
        SELECT @message='要回复的贴子已经被删除!'
        return
       END
     ELSE
       BEGIN
        IF (@rootid=0) SELECT @rootid=@id  ——回复的是根贴,取其id为新加贴的rootid
        SELECT @endnum=ordernum where rootid=@rootid and ordernum>@begnum order by ordernum
        IF (@endnum=0)
          SELECT @ordernum=@begnum+65536   ——回复的是最后一贴,可以在此限制@ordernum的范围以防溢出
        ELSE
**          BEGIN
**            IF @endnum-@begnum>1           ——精度仍能分辨。此处的1为精度标记,适合于基数字段为int,如果基数字段为numeric字段,请酌情选娶(呸呸呸,错别字来了),目的是使基数精度过小时限制深度增加,避免显示时的紊乱
**              SELECT @ordernum=(@begnum+@endnum)/2,@deep=@deep+1  ——关键,取排序基数中值
**            ELSE
**              SELECT @ordernum=@begnum     ——限制深度不能再增加,此贴与回复贴平行显示,如果存在parentid字段,则要取parentid和回复贴的parentid一样
**          END 
**        INSERT into forum (rootid,deep,ordernum,……) values(@rootid,@deep,@ordernum,……)
       END
    END
  Select @message='成功'
  return

剪枝存储过程改为:

CREATE PROCEDURE [del] @keyid int,@message varchar(50) OUTPUT  ———keyid为要删除的贴子id号,如果是新贴则为0,@message为出错信息
AS
DECLARE @rootid int,@id int,@deep int,@begnum float,@endnum float
SELECT @rootid=0,@deep=0,@begnum=0,@endnum=0,@id=0
SELECT @id=id,@begnum=ordernum,@rootid=rootid,@deep=deep from forum where id=@keyid
IF (@id=0)
  BEGIN
   SELECT @message='该贴子不存在!"
   return
  END
ELSE
  BEGIN
   SELECT @endnum=ordernum from forum where rootid=@rootid and deep<=@deep and ordernum>@begnum order by ordernum
   IF (@endnum=0)    ——要删除的是最后一个子枝或是根贴
     DELETE FROM forum where ordernum>=@begnum and (rootid=@rootid or id=@rootid)
   ELSE
**     BEGIN
**       IF @begnum=@endnum
**         DELETE FROM forum where id=@id and (rootid=@rootid or id=@rootid) ——已经受精度限制的枝,只删当前贴
**       ELSE
**         DELETE FROM forum where ordernum>=@begnum and ordernum<@endnum and (rootid=@rootid or id=@rootid)
**     END
  END


   虽然是限制,但此限制应该是必须的,因为实际上的回复深是不能太大的(就象我在这里灌到八九层的时候,讨饭猫就大叫“打住打住”了,呵呵)

   欢迎访问我的个人主页http://swuse.yeah.net(原来bigeagle是说我这一句话“目的明显啊”)





--------------------------------------------------------------------------------

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -