前兩天我們介紹了一種新的存儲無限級分類方法,但是讀出分類的時候怎麼實現樹形顯示呢?方法很簡單,我們自己定義一個樹形的數據結構,然後根據數據庫存儲的節點的深度來插入到樹裡面,當然顯示的時候需要用遞歸來顯示一下,不過這裡的遞歸只是在內存裡面遞歸,效率是相當高的。
在數據庫讀出數據的時候直接按照 LID 來進行 ASC 排序就可以了,默認的排列順序就是按照樹走的,大家可以插入一些數據,並讀取一下就可以很明了的看到順序了,插入樹循環的時候只需要對深度進行運算就可以了。
下面我只寫出了一些關鍵地方的代碼,具體的代碼自己試著多寫寫在紙上多畫畫應該就明白了。
另外就是想說下,這種分類算法只適用於一般的樹形分類,並不適用於插入數據比較頻繁的樹形結構,比如說無限次回復的評論,無限次回復的評論有另外一種更適合的算法。
首先我們定義一個樹形的數據結構:
public class ZoneList { private readonly ZoneList _Parent = null; private readonly List<ZoneList> _Childs = new List<ZoneList>(); private readonly ZoneItem _Value = null; public ZoneList Parent { get { return _Parent; } } public List<ZoneList> Childs { get { return _Childs; } } public ZoneItem Value { get { return _Value; } } public ZoneList Root { get { ZoneList curNode = this; while (curNode.Parent != null) { curNode = curNode.Parent; } return curNode; } } public ZoneList() { } public ZoneList(ZoneItem value, ZoneList parent) { _Value = value; _Parent = parent; } public ZoneList AddChild(ZoneItem value) { ZoneList nZoneList = new ZoneList(value, this); _Childs.Add(nZoneList); return nZoneList; } } 然後讀取數據庫並插入到樹:
public ZoneList Select() { ZoneList oZoneList = new ZoneList(); ZoneItem oZoneItem; Int32 intDee = 0; SqlDataReader oData = SiteSQL.ExecuteReader("ZoneSelect"); while (oData.Read()) { oZoneItem = new ZoneItem(); oZoneItem.ID = oData.GetInt32(0); oZoneItem.Tree = oData.GetInt32(1); oZoneItem.Name = oData.GetString(2); intDee = intDee - oZoneItem.Tree; for (Int32 intI = 0; intI <= intDee; intI++) { oZoneList = oZoneList.Parent; } oZoneList = oZoneList.AddChild(oZoneItem); intDee = oZoneItem.Tree; } oData.Close(); return oZoneList.Root; } 顯示的時候直接用遞歸就可以了:
private void ZoneOutWrite(ZoneList oZoneList) { foreach (ZoneList oZoneNode in oZoneList.Childs) { Response.Write(String.Format("<li id="zv_{0}"><span id="zName_{0}">{1}</span>", oZoneNode.Value.ID, oZoneNode.Value.Name)); if (oZoneNode.Childs.Count > 0) { Response.Write("<ul>"); ZoneOutWrite(oZoneNode); Response.Write("</ul>"); } Response.Write("</li>"); } }