树形递归遍历实现多级评论

原创 2015年11月20日 18:38:32

最近参加了学校的网页设计大赛,做了一个论坛网站,期间后台的多级评论用了我很多时间,什么是多级评论呢,也就是针对某一条评论,其他用户都可以在该评论基础上回复对方,这样也就形成了一条树形结构,我用了递归来实现树的遍历,感觉这个算法很有用,在许多方面都有可能用到,比如说像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#写的,其他语言实现也是这样的思路,希望对你有帮助。

相关文章推荐

Java实现通过递归遍历树形结构

树形结构在数据库的设计过程中是一种比较常见的模型,指的是各元素之间存在‘一对多’的结构模型。在树形结构中,树根结点没有前驱结点,其余每个结点有且只有一个前驱结点。叶子结点没有后续结点,其余每个结点的后...

Java实现树结构数据的递归与非递归遍历

递归与非递归的遍历 递归在很多情况下我们都会使用,比如著名的汉诺塔问题,有时候我们遍历一棵树形数据结构的数据也会需要用到递归,但是并不是绝对。原因是:以递归遍历一棵树型结构的数据为例,当这个树足够深的...

MySQL 实现树形的遍历(关于多级菜单栏以及多级上下部门的查询问题)

前言:        关于多级别菜单栏或者权限系统中部门上下级的树形遍历,oracle中有connect by来实现,mysql没有这样的便捷途径,所以MySQL遍历数据表是我们经常会遇到的头痛问题,...
  • mchdba
  • mchdba
  • 2014年09月15日 00:11
  • 39236

无限级遍历树(递归)

转自:http://www.iteye.com/topic/1122691 C# 中遍历树 ajax读取数据 递归算法实现数据树结构输出  数据表格字段为:id,Name,pID(父级ID) ...

php无限级分类实现评论及回复

经常在各大论坛或新闻板块详情页面下边看到评论功能,可以直接发表评论内容,可以对别人的评论进行回复,别人又可以对你的回复再次评论或回复,如此反复,理论上可以说是没有休止,从技术角度分析很容易想到运用无限...
  • Jo_Andy
  • Jo_Andy
  • 2015年05月18日 13:46
  • 10337

关于无限级理解,及其树形结构

首先在表中含有parent_id字段 树级菜单的顶层parent_id=0 那么如何根据顶层菜单查找它所属的子级菜单呢? 思路如下 : 首先找到parent_id=0的记录(可以有多条,意味的...

不用递归,C#实现无限层级树

首先是对象的属性: public class ResChapter { public int Id { get; set; } public string ...

C# TreeView 建立、遍历树(递归)

C#gui程序中建立树状结构、遍历树状结构、树状结构节点选中联动(选中父节点时,自动选中其全部子节点,取消选中的某子节点,取消其相应的所有父节点的选中),读取选中节点信息。...
  • heivy
  • heivy
  • 2016年12月07日 15:59
  • 3360

【树形递归】

C#树形递归,部门树状图 如果数据库中存在的department部门表,其中ID为主键,PID为父类,Name为部门名称,设计如下: public class department {...

C# 递归显示 TreeView 树状菜单树!

///         /// 初始化显示树型菜单         ///         private void showTreeviewMenu()         {           ...
  • ufocode
  • ufocode
  • 2015年01月20日 12:05
  • 1107
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:树形递归遍历实现多级评论
举报原因:
原因补充:

(最多只允许输入30个字)