前兩天我們介紹了一種新的存儲無限級分類方法,但是讀出分類的時候怎麼實現樹形顯示呢?方法很簡單,我們自己定義一個樹形的數據結構,然後根據數據庫存儲的節點的深度來插入到樹裡面,當然顯示的時候需要用遞歸來顯示一下,不過這裡的遞歸只是在內存裡面遞歸,效率是相當高的。
在數據庫讀出數據的時候直接按照 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>");
- }
- }