绘制树结构
2016-09-28 17:12
489 查看
树的表示方法有双亲表示法、孩子表示法、双亲孩子表示法、孩子兄弟表示法,具体请参考http://blog.csdn.net/xiazdong/article/details/7296257。其中前三种基于数组,最后一种基于链表。我定义的数节点数据结构为
我想在界面上绘制这棵树,想了很多种树的表现形式,觉得难以实现。由于我的这棵树是创建磁盘快照产生的,于是我参考了vmware中快照的展示,如下:
参考上图,发现第一个子快照和父快照处于同一横向水平线上,而兄弟节点处于竖向垂直线上。并且每一个子节点在其前一个兄弟节点绘制完毕后才绘制,所以其所在垂直方向的深度为其前一个兄弟节点(包括这个兄弟节点的子节点)锁绘制的最大深度加1。根据上图,可以给每一个快照点一个坐标方便绘制,例如Debug Mode的坐标为(2,0),而Debug Adv的坐标为(3,2)。于是我又在之前树结点定义加入了坐标值:
typedef struct _TREENODE { char val; _TREENODE* Parent; _TREENODE* Child; _TREENODE* Sibling; }TREENODE, *PTREENODE;也就是孩子兄弟表示法,附加一个指向父节点的指针。
我想在界面上绘制这棵树,想了很多种树的表现形式,觉得难以实现。由于我的这棵树是创建磁盘快照产生的,于是我参考了vmware中快照的展示,如下:
参考上图,发现第一个子快照和父快照处于同一横向水平线上,而兄弟节点处于竖向垂直线上。并且每一个子节点在其前一个兄弟节点绘制完毕后才绘制,所以其所在垂直方向的深度为其前一个兄弟节点(包括这个兄弟节点的子节点)锁绘制的最大深度加1。根据上图,可以给每一个快照点一个坐标方便绘制,例如Debug Mode的坐标为(2,0),而Debug Adv的坐标为(3,2)。于是我又在之前树结点定义加入了坐标值:
typedef struct _TREENODE { char val; int i; int j; _TREENODE* Parent; _TREENODE* Child; _TREENODE* Sibling; }TREENODE, *PTREENODE;初始化根节点坐标值为(0,0),而后在遍历树的过程中确定每个结点的坐标,并绘制(输出)树结点,以下为完整的代码
// PrintTree.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <iostream>
#include <Windows.h>
using namespace std;
typedef struct _TREENODE { char val; int i; int j; _TREENODE* Parent; _TREENODE* Child; _TREENODE* Sibling; }TREENODE, *PTREENODE;
PTREENODE AddNode(PTREENODE p, char val)
{
PTREENODE pn = new TREENODE;
pn->val = val;
pn->Child = pn->Sibling = NULL;
pn->Parent = p;
if (p->Child == NULL)
{
p->Child = pn;
}
else
{
p = p->Child;
while (p->Sibling != NULL)
{
p = p->Sibling;
}
p->Sibling = pn;
}
return pn;
}
int Print(PTREENODE p)
{
if (p == NULL)
return 0;
int depth = p->j;
cout<<p->val<<"("<<p->i<<","<<p->j<<")"<<endl;
//遍历子节点
if (p->Child)
{
p->Child->i = p->i + 1;
p->Child->j = p->j;
depth = Print(p->Child);
}
//打印兄弟节点
if(p->Sibling)
{
depth++;
p->Sibling->j = depth;
p->Sibling->i = p->i;
depth = Print(p->Sibling);
}
return depth;
}
int _tmain(int argc, _TCHAR* argv[])
{
TREENODE root;
ZeroMemory(&root, sizeof(root));
root.val = 'A';
PTREENODE pB = AddNode(&root, 'B');
PTREENODE pC = AddNode(&root, 'C');
PTREENODE pD = AddNode(&root, 'D');
PTREENODE pE = AddNode(pB, 'E');
PTREENODE pF = AddNode(pB, 'F');
PTREENODE pG = AddNode(pB, 'G');
PTREENODE pH = AddNode(pC, 'H');
PTREENODE pI = AddNode(pD, 'I');
PTREENODE pJ = AddNode(pD, 'J');
PTREENODE pK = AddNode(pG, 'K');
Print(&root);
return 0;
}
相关文章推荐
- LINQ to XML
- HTML5 video播放视频的方法
- 记录iOS开发中Xcode所见的错
- define总结
- Long short-term memory 论文小记
- 调试大型matlab数值计算程序的经,
- 业务建模利器-业务序列图
- Windows7中IIS简单安装与配置(详细图解)
- 小端字节序和大端字节序
- PHP获取上周、本周、上月、本月、本季度、上季度时间方法大全
- tableView的separatorInset设置
- Android应用开发网络请求 HttpClient和HttpURLConnection的区别
- 解决jackson 序列化这个对象出现无限递归的问题
- shiny安装使用入门
- 【微信JSSDK】PHP版微信录音文件下载
- .net后台使用post方式对指定地址的方法传值并且获取结果的方法
- 几行代码帮你搞定屏幕适配
- 局部内部类和非静态成员内部类
- 汇编学习笔记(二) -- 输出256个ASCII字符
- ffmpeg混音(将多个声音合成一个)命令