如何让数据结构可视化?
来⾃:程序员⼩灰
当我们实现⼀个⽐较复杂的数据结构,⽐如⼆叉树、图、跳表,Debug的时候怎么验证⾃⼰写的函数对不对呢?⼀个⽅法是将数据结构可视化,与理论上的结果⽐较即可。
请出主⾓: Graphviz,带⼀种解释语⾔ dot ,可以⽤简明的代码作图。
之所以推荐这个是因为它可以⾃动排版
1. 安装
作者系统为win10,其他操作系统应该⼤同⼩异。
安装时需要勾选添加环境变量:
添加环境变量 2. 渲染
有vscode的读者可以安装⼀个vscode插件:
安装vscode插件
安装完成后,新建⼀个 .dot ⽂件,右上⾓会出现⼀个渲染按钮:
渲染按钮
没有vscode的读者可以使⽤命令⼿动渲染: dot -Tpng 你的代码⽂件名 -o 输出图⽚⽂件名
3. 编写代码
⼀个空的dot代码(什么都不渲染):
digraph {
}
四个样例渲染效果
如图左上,可以使⽤下⾯代码,来创建⼀个名字为a的结点
digraph {
a
}
如图左下,通过 label 的修改可以改动结点显⽰的⽂字。
如图左下,通过 label 的修改可以改动结点显⽰的⽂字。
如图右上,通过 style = "dotted" 可以让其外侧圈边成虚线(可以⽤来显⽰NULL结点)代码中的引号疑似不是必须的,建议保留。
digraph {
a[label = "⽂字", style = "dotted"]
}
通过结点名称 -> 结点名称来创建⼀条线。
同理也可以使⽤ dotted ,(虚线⽤于连接NULL结点)。
这个 taillabel 可以在靠近第⼀个结点处显⽰⼀个数值(可⽤于显⽰结点中的⼀个数值)digraph {
node1[label = "A"]
node2[label = "B"]
node1 -> node2[style = dotted, taillabel = "0"]
}
tips:建议将结点的数据,也就是 value ,拿到 node[label = ] 中显⽰,最突出、显眼。
4. 坑3.4.1 NULL补位
NULL,空指针,在C++中被定义为 0
⼀个正常结点缺失左或右⼦结点时,会使⽤NULL指针来填补空缺。
正是因为其⾃动排版的功能,会导致⼀些坑。
举个例⼦,我们要画⼀个这样的⼆叉树:
1
|
-
------
| |
0没有右孩⼦( NULL结点)
因为我们不能使⽤开头为数字作为变量名,所以我们的命名规则为: n + 数字。
绘画效果:
NULL结点补位
我们发现,如果不使⽤⼀个结点NULL来补位,树被拉成了⼀个链。
我们只需要使⽤⼀层NULL结点来补位,这样结构就渲染正常了。
3.4.2 命名
两个结点名字相同,会被判定为⼀个结点:
结点名称相同
虽然这种情况在⼆叉搜索树中不存在,但是这⾥还是提⼀下。
怎么区分不同的结点呢?我们可以通过C++程序中结点的指针来命名。
结点名称: n + 指针
即使两个结点存储内容相同,但是在电脑中的内存地址⼀定不同。
但是NULL结点都会被命名为 n0 ,⽆法区分,怎么办呢?
我这⾥使⽤的解决⽅法:NULL结点命名规则为 n + 叶⼦结点指针 + 是左⼦结点还是右⼦结点AVL样例 3.5 代码
这个代码是基于Part 1中结点的定义来实现的。
voidDEBUG{ // 使⽤了part 2中的软件来绘图,调试神器
FILE *fp = NULL;
fp = fopen( "./output.dot", "w"); // ./output.dot 为输出的⽂件名
fprintf(fp, "digraph {\n");
deque<node*> q; // 前序遍历,使⽤队列实现
node *current;
q.push_back(root);
while(!q.empty) {
current = q.front;
q.pop_front;
if(current == NULL) {
continue;
continue;
}
fprintf(fp, "\tn%d[label = \"%d\"]\n", current, current->value);
for( inti = 0; i < 2; ++i) {
if(current->child[i]) {
fprintf(fp, "\tn%d -> n%d[style = blod]\n", current, current->child[i]); q.push_back(current->child[i]);
} else{
数据可视化是什么fprintf(fp, "\tnull%d%d[label = \"NULL\", style = dotted]\n", current, i); fprintf(fp, "\tn%d -> null%d%d[style = dotted]\n", current, current, i); }
}
}
fprintf(fp, "}");
fclose(fp);
}
参考资料
[1]
--- EOF ---
推荐↓↓↓
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论