读书人

怎么从树叶层开始建树

发布时间: 2013-10-08 17:08:58 作者: rapoo

如何从树叶层开始建树?

在开发软件的过程中,遇到一个树形结构的问题,如下图:

怎么从树叶层开始建树

由于树形结构太大,只显示部分叶节点,并且报价是叶节点的数量和报价的成积。

问题经分析很显然:变成了如下两个问题:

1从树的根节点开始建树就是一个简单的递归,但现在的问题是从树的叶节点开始如何建树,涉及到一个如何合并子节点的问题。

2如何根据叶节点的数量和报价计算各级父节点的报价?


1如何从树的叶节点开始如何建树?

有一种思路,就是按照正常思路建好后,然后把没有子节点的删掉,很麻烦。

于是想着能不能通过叶节点的递归一层一层向上,最终完成树的创建。

最总实现代码如下:

public class TreeNode{    private int m_ID;    public int ID    {        get { return ID; }        set { ID = value; }    }    private int? m_ParentID;    public int? ParentID    {        get { return m_ParentID; }        set { m_ParentID = value; }    }    private int? m_Count;    public int? Count    {        get { return m_Count; }        set { m_Count = value; }    }    private string m_PL_Code;    public string PL_Code    {        get { return m_PL_Code; }        set { m_PL_Code = value; }    }      private string m_Name;    public string Name    {        get { return m_Name; }        set { m_Name = value; }    }    private double m_Price = 0;//默认为0,    public double Price    {        get        {            if (m_Price == 0)//如果是默认值,则调用方法计算            {                m_Price = GetPrice();             }            return m_Price;        }        set { m_Price = value; }    }    /// <summary>    /// 通过子节点计算此节点的报价    /// </summary>    /// <returns></returns>    private double GetPrice()    {        if (m_Price > 0)//已经计算过,直接返回        {            return m_Price;        }        double PriceTemp = 0;        if (children != null && children.Count > 0)        {            foreach (TreeNode node in children)// 通过子节点计算此节点的报价            {                if (node.Count.HasValue)                {                    PriceTemp += node.Count.Value * node.Price;                }                else                {                    PriceTemp += node.Price;                }            }        }              return PriceTemp;    }    private List<TreeNode> m_children;    public List<TreeNode> children    {        get { return m_children; }        set { m_children = value; }    }    /// <summary>    /// 返回需要的树    /// </summary>    /// <param name="listAllNodes">所有的节点信息</param>    /// <param name="dicNode">键为父节点编号,值为父节点对应的子节点  ,初始为需要显示的叶节点</param>    /// <returns></returns>    public static List<TreeNode> GeTree(List<TreeNode> listAllNodes, Dictionary<int, List<TreeNode>> dicNode)    {        int rootNodeId = -1;//虚拟的根节点编号        while (!dicNode.ContainsKey(rootNodeId)) //如果没有到根节点继续        {            dicNode = GetOneLevelNodes(listAllNodes, dicNode);        }        return dicNode[rootNodeId];    }    /// <summary>    /// 返回某一层的所有节点,包含子节点    /// </summary>    /// <param name="listAllNodes">所有的节点信息</param>    /// <param name="dicNode">键为父节点编号,值为父节点对应的子节点</param>    /// <returns></returns>    private static Dictionary<int, List<TreeNode>> GetOneLevelNodes(List<TreeNode> listAllNodes, Dictionary<int, List<TreeNode>> dicNode)    {        int rootNodeId = -1; //虚拟的根节点编号              List<int> ParentsIdList = new List<int>();        ParentsIdList.AddRange(dicNode.Keys);//这次需要添加的节点编号        Dictionary<int, List<TreeNode>> dicNode2 = new Dictionary<int, List<TreeNode>>();//键为父节点编号,值为父节点对应的子节点        for (int i = listAllNodes.Count - 1; i >= 0; i--)        {            TreeNode item = listAllNodes[i];            if (ParentsIdList.Contains(item.ID))            {                               int parentId = rootNodeId;//默认为顶级节点                if (item.ParentID.HasValue)//如果存在父节点                {                    parentId = item.ParentID.Value;                }                List<TreeNode> children = dicNode[item.ID];//获取此节点对应的子节点                item.children = children;//添加子节点                AddOneNode(parentId, dicNode2, item);//添加节点到字典中                listAllNodes.RemoveAt(i);//移除已经处理的节点            }        }        return dicNode2;    }    /// <summary>    /// 合并具有相同父节点的兄弟节点    /// </summary>    /// <param name="parentId">需要处理的节点的父节点</param>    /// <param name="dicNode">此层对应的节点字典</param>    /// <param name="node">需要处理的节点</param>    private static void AddOneNode(int parentId, Dictionary<int, List<TreeNode>> dicNode, TreeNode node)    {        if (dicNode.ContainsKey(parentId))//如果有        {            dicNode[parentId].Add(node);//如果具有相同的父节点,则添加到相应的兄弟节点列表中        }        else//如果没有        {            List<TreeNode> listChild = new List<TreeNode>();            listChild.Add(node);//兄弟节点列表            dicNode.Add(parentId, listChild);        }    }   }

读书人网 >编程

热点推荐