樹形遞迴遍歷實現多級評論
阿新 • • 發佈:2019-02-09
最近參加了學校的網頁設計大賽,做了一個論壇網站,期間後臺的多級評論用了我很多時間,什麼是多級評論呢,也就是針對某一條評論,其他使用者都可以在該評論基礎上回復對方,這樣也就形成了一條樹形結構,我用了遞迴來實現樹的遍歷,感覺這個演算法很有用,在許多方面都有可能用到,比如說像QQListView分組顯示都可以用它來實現。
具體實現思路:
1、通過構建節點來記錄資料,節點要求:記錄父節點;記錄自身節點,記錄子節點,記錄節點所在樹。
2、將已經記錄了資訊的節點儲存到集合表中,對集合表進行遍歷排序。
3、將排好序的集合表用於專案中遍歷顯示。
接下來給大家展示核心程式碼:
我還是來一張網站多級評論圖片(嘿嘿):
一、Node類:
public class Node
{
private int id;//自己的id,-1時表示葉子節點
private int p_id;//父節點id,0時表示根節點
private int root_number;//這個是每條樹的唯一標識,表示該節點所在根
private Node parent;//記錄父節點,每個節點只有一個父節點
private List<Node> children;//記錄子節點,子節點可以有多個
//其他屬性根據具體需求新增,以上都是必須的
public Node(int id, int p_id, int root_number)
{
this.id = id;
this.p_id = p_id;
this.root_number = root_number;
}
public int getId()
{
return this.id;
}
public int getPId()
{
return this.p_id;
}
public int getRootNumber()
{
return this .root_number;
}
public void setParent(Node parent)
{//設定父節點
this.parent = parent;
}
public Node getParent()
{//獲取該節點的父節點
return this.parent;
}
public void setChildren(Node child)
{//記錄子節點
this.children.Add(child);
}
public boolisRoot()
{//判斷是否為根
return this.p_id == 0;
}
public bool isLeaf()
{//判斷是否為葉子節點
return this.id == -1;
}
public List<Node> getChidrenList()
{//獲取該節點的的所有子節點集合表
return this.children;
}
}
二、NodesHelper類:節點進行遍歷排序
public class NodesHelper
{
public static List<Node> getConvertNode(List<Node> list) {//對外開放介面,返回排序後的集合表
//各節點之間建立連線關係
connectNodes(list);
//獲取所有的根節點
List<Node> rootNodes = getRootNodes(list);
//建立空表,儲存排序後的節點
List<Node> result = new List<Node>();
for (int i = 0; i < rootNodes.Count; i++)
{//根據每個根節點,將其所屬節點新增到空表中
//遞迴新增節點
addNodeToResult(result, rootNodes[i]);
}
return result;
}
private static void connectNodes(List<Node> list)
{//各節點之間建立連線關係
for (int i = 0; i < list.Count -1; i++)
{
Node nodeLast = list[i];
for (int j = i + 1; j < list.Count; j++)
{
Node nodeNext = list[j];
if (nodeLast.getRootNumber() == nodeNext.getRootNumber())//判斷是否處於同一樹
{
if (nodeNext.getPId() == nodeLast.getId())
{
nodeLast.setChildren(nodeNext);
nodeNext.setParent(nodeLast);
}
else if (nodeNext.getId() == nodeLast.getPId())
{
nodeNext.setChildren(nodeLast);
nodeLast.setParent(nodeNext);
}
}
}
}
}
private static List<Node> getRootNodes(List<Node> list)
{//獲取所有的根節點
List<Node> rootNodes = new List<Node>();
int length = list.Count;
for (int i = 0; i < length; i++)
{
if (list[i].isRoot())
{
rootNodes.Add(list[i]);
}
}
return rootNodes;
}
private static void addNodeToResult(List<Node> result, Node node)//遞迴新增節點
{
result.Add(node);
if (node.isLeaf())
{
return;
}
List<Node> list = node.getChildrenList();
for (int i = 0; i < list.Count; i++)
{
addNodeToResult(result, list[i]);
}
}
}
好了,程式碼就這些了。我用的是C#寫的,其他語言實現也是這樣的思路,希望對你有幫助。