N叉树节点绘制
2015-08-11 17:24
267 查看
一、接地坐标计算思路
由于在绘制N叉树的时候要每一个节点不能重叠,因此不能从顶节点开始绘制,只能先绘制叶子节点,在根据叶子节点的坐标来求得父节点的位置;
1、绘制一个节点:在绘制一个节点的时候先遍历绘制所有的子节点,再通过计算求得该节点坐标并进行绘制;
2、在绘制叶子节点时要注意,由于可能各个叶子节点的深度不同,因此每一个叶子节点在深度方向上的值是不能重叠的(即X不能相同),因此在画每一个叶子节点的时候要记录该叶子节点的X值,后面的叶子节点必须在这个叶子节点的X的基础上加上间隔;这样叶子节点X就不会重复,最后每一个节点就不会重复;
3、各个节点的Y值可以通过间隔与节点升读求得;
下面代码知识求得节点坐标方法;
N叉树节点定义
由于在绘制N叉树的时候要每一个节点不能重叠,因此不能从顶节点开始绘制,只能先绘制叶子节点,在根据叶子节点的坐标来求得父节点的位置;
1、绘制一个节点:在绘制一个节点的时候先遍历绘制所有的子节点,再通过计算求得该节点坐标并进行绘制;
2、在绘制叶子节点时要注意,由于可能各个叶子节点的深度不同,因此每一个叶子节点在深度方向上的值是不能重叠的(即X不能相同),因此在画每一个叶子节点的时候要记录该叶子节点的X值,后面的叶子节点必须在这个叶子节点的X的基础上加上间隔;这样叶子节点X就不会重复,最后每一个节点就不会重复;
3、各个节点的Y值可以通过间隔与节点升读求得;
下面代码知识求得节点坐标方法;
N叉树节点定义
public class NXNode { public int X; public int Y; public List<NXNode> Children = new List<NXNode>(); int _depth = -1; public int Depth { get { return _depth; } } public int ID { get; private set; } NXNode _parentNode = null; public NXNode ParentNode { get { return _parentNode; } } /// <summary> /// 构件一个N叉树的节点 /// </summary> /// <param name="id"></param> public NXNode(int id) { this.ID = id; } /// <summary> /// 添加一个节点 /// </summary> /// <param name="node"></param> public void AddChildren(NXNode node) { if (node != null) { Children.Add(node); node._parentNode = this; node._depth = this.Depth + 1; UpdataChildrenDeth(node); } } /// <summary> /// 移除一个节点 /// </summary> /// <param name="node"></param> /// <returns></returns> public bool RemoveChildren(NXNode node) { if (node != null) { node._parentNode = null; node._depth = -1; UpdataChildrenDeth(node); return Children.Remove(node); } else { return false; } } /// <summary> /// 在添加和或者移除一个节点时候更新该节点子节点的深度值 /// </summary> /// <param name="node"></param> /// <returns></returns> bool UpdataChildrenDeth(NXNode node) { try { if (node.Children.Count > 0) { foreach (NXNode item in node.Children) { item._depth = node.Depth + 1; UpdataChildrenDeth(item); } } return true; } catch (Exception) { return false; } } }
下面是N叉树代码
public class NXNodeTree { /// <summary> /// 节点间的宽度 /// </summary> public static int NodeWSpacing = 10; /// <summary> /// 上下级节点的高度 /// </summary> public static int NodeHSpacing = 10; /// <summary> /// Root 节点是虚拟的节点,在绘画的是时候不应该画出来 /// </summary> public NXNode Root { get; private set; } public NXNodeTree(int maxNodeId) { NXNode rootNode = new NXNode(maxNodeId); this.Root = rootNode; } /// <summary> /// 用所给的PMapNode创建一棵NX树,这里的list的元素应该不能太多,要求nodeList进行排序 /// </summary> /// <param name="list"></param> /// <returns></returns> static public NXNodeTree CreatNXNodeTree(List<PMapNode> nodeList) { try { if (nodeList != null && nodeList.Count > 0) { Dictionary<int, NXNode> dicNXNodes = new Dictionary<int, NXNode>(); int nodeParentID = nodeList[0].ParentID; NXNodeTree nXNodeTree = new NXNodeTree(nodeParentID); dicNXNodes.Add(nodeParentID, nXNodeTree.Root); foreach (PMapNode item in nodeList) { NXNode node = new NXNode(item.ID); if (dicNXNodes.ContainsKey(item.ParentID)) { NXNode parentNode = dicNXNodes[item.ParentID]; parentNode.AddChildren(node); dicNXNodes.Add(item.ID, node); } else { } } dicNXNodes.Clear(); return nXNodeTree; } } catch (Exception ex) { //TODO:记录错误 } return null; } /// <summary> /// 计算树节点的坐标 /// </summary> /// <param name="nXNodeTree"></param> public static void IniNXNodeTreeXY(NXNodeTree nXNodeTree) { if (nXNodeTree != null) { NXNode rootNode = nXNodeTree.Root; foreach (NXNode item in rootNode.Children) { CalculateNXNodeXY(item); } } } /// <summary> /// 节点坐标的最小的X值 /// </summary> static int drawMinX = 0; /// <summary> /// 如果需要绘制节点的时候对节点进行坐标计算 /// </summary> /// <param name="node"></param> static void CalculateNXNodeXY(NXNode node) { if (node.Children.Count > 0) { int maxX = 0; foreach (NXNode childrenNode in node.Children) { CalculateNXNodeXY(childrenNode); maxX = childrenNode.X; } int minX = node.Children[0].X; node.X = (minX + maxX + 1) / 2; node.Y = node.Depth * NodeHSpacing; } else { drawMinX += NodeWSpacing; node.X = drawMinX; node.Y = node.Depth * NodeHSpacing; } } }
</pre><pre name="code" class="csharp">上下级关系定义类
</pre><pre name="code" class="csharp"> public class PMapNode { public int X; public int Y; public int ID { get; private set; } public PMapNode(int id, int parentID) { ID = id; ParentID = parentID; } public string Name { get; set; } public int ParentID { get; private set; } public int Generation { get; private set; } }
相关文章推荐
- 26-网络编程-13-网络编程(TCP协议-练习-文本转换客户端)
- 浅谈反射机制
- Linux进程间通信之管道(pipe)、命名管道(FIFO)与信号(Signal)
- POJ1611
- Java基础-ArrayList中ConcurrentModificationException错误解决
- iOS 软件进行版本更新
- servlet单线程
- Vector线程安全
- java虚拟机原理图解1
- 26-网络编程-12-网络编程(TCP协议-服务端和客户端交互)
- bzoj2066: [Poi2004]Gra
- hdu 4068 福州赛区网络赛H 排列 ***
- 'ascii' codec can't encode characters in position 1-5: ordinal not in range(128)
- HDU 1495 非常可乐(最笨办法版)
- C语言str函数系列总结
- 博客
- 为什么程序员的业余项目大多都死了?
- SQL
- 注册Tomcat服务为系统服务
- 26-网络编程-10-网络编程(TCP协议-客户端)