树的可视化操作
如何将建成的树用图片的方式展现出来,在这次课设的时候发现一种方法, 借此来分享一波。
以二叉树为例。
用到的语言: c++,python。
首先,当然是要建好一棵树,顺便复习一下二叉树的构成。
struct TreeNode
{
int data;
struct TreeNode* Left = NULL;
struct TreeNode* Right = NULL;
};
//这边展现通过前序和中序建立唯一二叉树
TreeNode* traversal(vector<int>& preorder, vector<int>& inorder)
{
if (preorder.size() == 0) return NULL;
//preorder前序 inorder中序 首先从前序中找到root
int rootValue = preorder[0];
TreeNode* root = new TreeNode;
root->data = rootValue;
if (preorder.size() == 1) return root;
int index;
//通过中序查找到目标值,分为两个部分
for (index = 0; index < inorder.size(); index++)
{
if (inorder[index] == rootValue) break;
}
//将前序和后序分别分为两部分
//中序 [0,index) [index+1,inorder.size())
vector<int> inorderLeft(inorder.begin(), inorder.begin() + index);
vector<int> inorderRight(inorder.begin() + index + 1, inorder.end());
//前序 [1,1 + index) [1+index,preorder.size())
vector<int> preorderLeft(preorder.begin() + 1, preorder.begin() + 1 + index);
vector<int> preorderRight(preorder.begin() + index + 1, preorder.end());
root->Left = traversal(preorderLeft, inorderLeft);
root->Right = traversal(preorderRight, inorderRight);
return root;
}
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
if (preorder.size() == 0) return NULL;
return traversal(preorder, inorder);
}
接下来用因为要用到python和graphviz,所以就先将遍历写进文件里啦,代码如下:
int Count = 0;
void dfsPrint(TreeNode* t, int m, FILE* fp)
{
if (t->Left)
{
Count++;
fprintf(fp, "node%d[label = %d];\n", Count, t->Left->data);
fprintf(fp, "node%d->node%d [dir = ;\n", m, Count);
dfsPrint(t->Left, Count, fp);
}
if (t->Right)
{
Count++;
fprintf(fp, "node%d[label = %d];\n", Count, t->Right->data);
fprintf(fp, "node%d->node%d;\n", m, Count);
dfsPrint(t->Right, Count, fp);
}
}
int main()
{
FILE* fp;
//这边注意文件类型是dot,可以让它自动生成
fp = fopen("D:\\PyCharm\\Project\\二叉树图.dot", "w+");
fprintf(fp, "digraph G{\n");
fprintf(fp, "node%d[label = %d];\n", 0, Treeroot->data);
dfsPrint(Treeroot, 0, fp);
fprintf(fp, "}");
fclose(fp);
return 0;
}
关于graphviz也不是很懂哈哈哈,简单介绍一下吧!
//例如下面这一串
digraph G{
A -> B;
A -> C;
C -> D;
}
就会产生这样的图
好像会转换成下面这个,好像是吧哈哈哈。
digraph G {
graph [bb="0,0,126,180"];
node [label="\N"];
A [height=0.5,
pos="63,162",
width=0.75];
B [height=0.5,
pos="27,90",
width=0.75];
A -> B [pos="e,35.304,107.15 54.65,144.76 50.288,136.28 44.853,125.71 39.959,116.2"];
C [height=0.5,
pos="99,90",
width=0.75];
A -> C [pos="e,90.696,107.15 71.35,144.76 75.712,136.28 81.147,125.71 86.041,116.2"];
D [height=0.5,
pos="99,18",
width=0.75];
C -> D [pos="e,99,36.104 99,71.697 99,63.983 99,54.712 99,46.112"];
}
因为结点的数可能相同,我就直接每个结点定义一个名字
node1[label = 1]//这种方式产生一个名为node1 值为1的结点
将文件写好了以后,就用强大的python来完成吧。
import graphviz
with open("二叉树图.dot", encoding='utf-8') as f:
dot_graph = f.read()
dot = graphviz.Source(dot_graph)
dot.view()
关于graphviz的安装我也来讲讲吧,因为百度的都是2.38,现在都2.47.3了,哎。
链接呈上 http://www.graphviz.org/download/
下载完就是安装了—记得吧那个path打勾,就省的自己去配置了。
然后Win + R cmd dot -version 出现一大串说明好了。
然后就python安装graphviz库,简单的就是Win + R cmd pip install graphviz
不行的话百度百度,嘻嘻~~
哈哈哈,当然,这生成的树有点丑,只有一个结点的时候不会往两边岔开,可以去研究研究哦~~
当然关于dot语言还有许多好用的东西,可以官网查看,链接上面那个。
第一次写文章,觉得这个挺有用的,分享分享嘻嘻~~