用中值排序基數法實現樹狀結構 (轉)
在BBS的編寫中,經常有人問怎樣實現樹狀結構?一個比較不負責任的回答是:使用遞迴演算法。當然,遞迴是一個可行的辦法
(二叉樹的歷遍也好象只能使用遞迴演算法),但對於BBS來說,這樣做勢必要進行大量的查詢(雖然可以使用過程來做,但要從根本上加度,則應該考慮更快的演算法)。
下面給出一個可行的徹底摒棄遞的實現樹狀結構的演算法。
下面給出另一種使用“使用中值排序基數法”實現樹狀結構:
一、主要思想:增加一個排序基數字段ordernum,回覆同一根貼的貼子中插入貼子時,排序基數ordernum取兩者的中值。
為了敘述的簡潔,在此只討論與樹狀結構有關的欄位。
在表中增加三個冗餘欄位,id——用於記錄根id,deep——用於記錄回覆的深度(為0時表示根貼),ordernum——排序基數(關鍵所在)。
表forum與(只列與樹狀結構有關的欄位):id rootid deep ordernum其中id、rootid、deep均為int型(deep可為tinyint型),ordernum為float型。
例:(在此為了簡單,使用一個小的起始排序基數,在實際應用中,應使用較大的起始基數,且應取2的整數次冪,如65536=2^16,下面所說的排序均指按ordernum從小到大排序)。
id rootid deep ordernum
1 0 0 0
2 1 1 64
______________________________
3 1 1 32 回覆第1貼,取1、2基數的中值即(0+64)/2
排序後結果為:
id rootid deep ordernum
1 0 0 0
3 1 1 32
2 1 1 64
______________________________
4 1 2 48 回覆第3貼,取3、2的基數中值即(32+64)/2
排序後結果為:
id rootid deep ordernum
1 0 0 0
3 1 1 32
4 1 2 48
2 1 1 64
______________________________
5 1 3 56 回覆第4貼,取4、2的基數中值即(48+64)/2
排序後的結果為:
id rootid deep ordernum
1 0 0 0
3 1 1 32
4 1 2 48
5 1 3 56
2 1 1 64
______________________________
6 1 2 40 回覆第3貼,取3、4的基數中值即(32+48)/2
排序後的結果為:
id rootid deep ordernum
1 0 0 0
3 1 1 32
6 1 2 40
4 1 2 48
5 1 3 56
2 1 1 64
這樣排序基數ordernum與回覆深度deep一起就實現瞭如下的樹狀結構:
id
1
3
6
4
5
2
二、插入的實現(如何確定排序基數,下面所指貼子均為同一根下的子貼)
(一)根ordernum定為0
(二)第一條回覆貼子基數定為2的整數次冪(如65536=2^16,可取更大的數)
(三)回覆最後一條貼子時,基數取最後一貼的基數ordernum再加上2的整數次冪(同上)
(四)回覆中間的貼子時,基數ordernum取前後貼子的基數中值
三、刪除的實現
刪除貼子(剪枝)時,只需找出下一個回覆深度deep小於或等於要刪貼子的回覆深度(deep)的貼子,然後將基數ordernum位於兩個貼子基數之間的貼子刪除即可實現剪枝。
如上例子中,要刪除3貼(基數為32)下的子枝,由於3的深度為1,下一個深度小於或等於1的貼子為2貼(它的基數為64),則只需刪除基數在32至64間(64除外)的貼子就行了。也就是刪除了3、6、4、5貼。要刪其它亦然。
四、顯示的實現
只需 * from forum order by rootid+id-sign(rootid)*id desc,ordernum,然後結合deep就可實現樹狀的顯示。
五、具體實現方法(以儲存過程為例)
加貼儲存過程:(省略註冊檢測以及積分部分內容)
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,@bem 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 ——回覆的是最後一貼
ELSE
SELECT @ordernum=(@begnum+@endnum)/2 ——關鍵,取排序基數中值
INSERT into forum (rootid,deep,ordernum,……) values(@rootid,@deep+1,@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
DELETE FROM forum where ordernum>=@begnum and ordernum
END
顯示儲存過程(略)
總結:由於省去了childnum欄位,因此如果想要知道根貼(或子貼)有多少個子貼,則需使用統計方法或增加對應的欄位記錄,該問題可不列為樹狀結構討論之列。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-995560/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- CSS 實現樹狀結構目錄CSS
- js生成動態樹狀結構及排序JS排序
- python 遞迴樹狀結構 和 排序Python遞迴排序
- 遞迴遍歷樹狀結構優雅實現遞迴
- json轉json樹狀結構JSON
- 論壇樹狀結構的展現
- TreeView樹狀結構View
- 資料結構與演算法——基數排序簡單Java實現資料結構演算法排序Java
- (戀上資料結構筆記):計數排序、基數排序 、桶排序資料結構筆記排序
- 資料結構 8 基礎排序演算法詳解、快速排序的實現、瞭解分治法資料結構排序演算法
- 樹結構與Java實現Java
- [php]運用變數引用實現一維陣列轉多維樹狀陣列PHP變數陣列
- 【資料結構與演算法】非比較排序(計數排序、桶排序、基數排序)資料結構演算法排序
- 基數排序--陣列模擬桶結構排序陣列
- PHP 陣列轉樹結構/樹結構轉陣列PHP陣列
- 資料結構之通用樹結構的實現資料結構
- 資料結構 桶排序 基數排序MSD c++ swift 版本資料結構排序C++Swift
- 基數排序-單連結串列實現【資料結構與演算法分析(c 語言描述)】排序資料結構演算法
- 資料結構與演算法分析(c 語言描述)基數排序 陣列實現資料結構演算法排序陣列
- PPT製作樹狀結構圖
- 資料結構——樹狀陣列資料結構陣列
- 【資料結構】實現紅黑樹!!!資料結構
- [Swing]樹形結構的實現
- 資料結構與演算法——排序演算法-基數排序資料結構演算法排序
- (樹)根據排序陣列或者排序連結串列重新構建BST樹排序陣列
- 樹狀的資料結構的建立資料結構
- 關於elementUI樹狀結構的bugUI
- tkinter中樹狀結構的建立(十四)
- 基於桶的排序之基數排序以及排序方法總結排序
- Java實現遞迴查詢樹結構Java遞迴
- Python資料結構——樹的實現Python資料結構
- 樹結構的應用
- Java 樹結構實際應用 四(平衡二叉樹/AVL樹)Java二叉樹
- 以樹狀結構顯示系統當前的任務(轉)
- 二叉排序樹的實現排序
- 資料結構與演算法(C#實現)系列---樹(二) (轉)資料結構演算法C#
- 資料結構與演算法(C#實現)系列---樹(三) (轉)資料結構演算法C#
- 資料結構與演算法(C#實現)系列---樹(一) (轉)資料結構演算法C#