绘制树结构

来源:互联网 发布:淘宝一千零一夜 在哪 编辑:程序博客网 时间:2024/06/16 06:13

树的表示方法有双亲表示法、孩子表示法、双亲孩子表示法、孩子兄弟表示法,具体请参考http://blog.csdn.net/xiazdong/article/details/7296257。其中前三种基于数组,最后一种基于链表。我定义的数节点数据结构为

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;}


0 0
原创粉丝点击