二叉树可视化--Graphviz

大家平时写C程序有没有种把内存里的数据结构全给画出来的冲动呢?数据量小的话,画起来还蛮简单,用viso,我前面的文章都用viso画的。之前写红黑树代码的时候,用的是命令行把整个树打印出来,不过只是一些小片段,很丑,还得自己手动再在纸上画一遍,非常麻烦,要是用程序就能把图画出来那就爽了。好了,推荐使用 Graphviz这个东东,so 一下就知道啦,功能挺丰富的,也提供了很多库(c,PHP,Python等),下面画一颗简单的红黑树(红黑树代码参考我前面的代码,下面只写画树的代码)直接看效果图:



这树怎么画的呢?参考官网 http://www.graphviz.org/Documentation.php

1.编写规则文件(可以用Graphviz自带的lib,如cgraph等生成,或者直接就用fprintf生成,可以简单看下中文的翻译 简单的dot规则

2.用Graphviz自带的一些工具例如dot等解析一下规则文件,然后生成图片(ps,jpg,png等)或者其它格式的文件。

生成方法:

首先Linux安装Graphviz,sudo apt-get install Graphviz,然后在终端中用如下命令生成图片格式:
dot -Tps graph1.dot -o graph1.ps //这是ps格式,你也可以改成jpg等格式。

dot -Tjpg graph1.dot -o graph1.jpg //这是jpg格式


下面是实现。

t.c//测试代码,用到的函数参考我前面写的红黑树文章的代码。

  1. void rbtree_fprint_node(rbtree_node * t,FILE *fp){  
  2.         if(t->color == RB_BLACK){  
  3.                 fprintf(fp,"node[shape=record,style=filled,color=black,fontcolor=white];\n");  
  4.         }else{  
  5.                 fprintf(fp,"node[shape=record,style=filled,color=red,fontcolor=white];\n");  
  6.         }  
  7.         fprintf(fp,"%d[label=\"<f0> | <f1> %d | <f2> \"];\n",t->key.value,t->key.value);  
  8. }  
  9. void rbtree_fprint_tree(rbtree_node * t,FILE *fp){  
  10.         if(rb_nil == t) return;  
  11.         if(t->parent ==  rb_nil){//root  
  12.                 rbtree_fprint_node(t,fp);  
  13.         }  
  14.   
  15.         if(t->left != rb_nil){  
  16.                 rbtree_fprint_node(t->left,fp);  
  17.                 fprintf(fp,"%d:f0:sw->%d:f1;\n",t->key.value,t->left->key.value);  
  18.         }  
  19.         if(t->right != rb_nil){  
  20.                 rbtree_fprint_node(t->right,fp);  
  21.                 fprintf(fp,"%d:f2:se->%d:f1;\n",t->key.value,t->right->key.value);  
  22.         }  
  23.         rbtree_fprint_tree(t->left,fp);  
  24.         rbtree_fprint_tree(t->right,fp);  
  25. }  
void rbtree_fprint_node(rbtree_node * t,FILE *fp){
        if(t->color == RB_BLACK){
                fprintf(fp,"node[shape=record,style=filled,color=black,fontcolor=white];\n");
        }else{
                fprintf(fp,"node[shape=record,style=filled,color=red,fontcolor=white];\n");
        }
        fprintf(fp,"%d[label=\"<f0> | <f1> %d | <f2> \"];\n",t->key.value,t->key.value);
}
void rbtree_fprint_tree(rbtree_node * t,FILE *fp){
        if(rb_nil == t) return;
        if(t->parent ==  rb_nil){//root
                rbtree_fprint_node(t,fp);
        }

        if(t->left != rb_nil){
                rbtree_fprint_node(t->left,fp);
                fprintf(fp,"%d:f0:sw->%d:f1;\n",t->key.value,t->left->key.value);
        }
        if(t->right != rb_nil){
                rbtree_fprint_node(t->right,fp);
                fprintf(fp,"%d:f2:se->%d:f1;\n",t->key.value,t->right->key.value);
        }
        rbtree_fprint_tree(t->left,fp);
        rbtree_fprint_tree(t->right,fp);
}
  1. int main(int argc,char *argv[]){  
  2.         rbtree_node *t,*p,*max,*min;  
  3.         int arr[] = {9,8,11,18,2,5,16,1,7,999,234,7662,387,928,454};  
  4.         int i;  
  5.         rbtree_init_nil();  
  6.         t = rbtree_create(15);  
  7.         t->color = RB_BLACK;  
  8.         for(i=0;i<15;i++){  
  9.                 rbtree_add(&t,arr[i]);  
  10.         }  
  11.         //rb tree print  
  12.         FILE *fp;  
  13.         fp = fopen("g2.dot","w+");  
  14.         fprintf(fp,"digraph G{\n");  
  15.         rbtree_fprint_tree(t,fp);  
  16.         fprintf(fp,"}");  
  17.         fclose(fp);  
  18. }  
int main(int argc,char *argv[]){
        rbtree_node *t,*p,*max,*min;
        int arr[] = {9,8,11,18,2,5,16,1,7,999,234,7662,387,928,454};
        int i;
        rbtree_init_nil();
        t = rbtree_create(15);
        t->color = RB_BLACK;
        for(i=0;i<15;i++){
                rbtree_add(&t,arr[i]);
        }
        //rb tree print
        FILE *fp;
        fp = fopen("g2.dot","w+");
        fprintf(fp,"digraph G{\n");
        rbtree_fprint_tree(t,fp);
        fprintf(fp,"}");
        fclose(fp);
}

最终生成的是 一个  dot文件,dot文件的语法上官网查,并不是很复杂。

  1. digraph G{  
  2. node[shape=record,style=filled,color=black,fontcolor=white];  
  3. 9[label="<f0> | <f1> 9 | <f2> "];  
  4. node[shape=record,style=filled,color=black,fontcolor=white];  
  5. 5[label="<f0> | <f1> 5 | <f2> "];  
  6. 9:f0:sw->5:f1;  
  7. node[shape=record,style=filled,color=red,fontcolor=white];  
  8. 18[label="<f0> | <f1> 18 | <f2> "];  
  9. 9:f2:se->18:f1;  
  10. node[shape=record,style=filled,color=black,fontcolor=white];  
  11. 2[label="<f0> | <f1> 2 | <f2> "];  
  12. 5:f0:sw->2:f1;  
  13. node[shape=record,style=filled,color=black,fontcolor=white];  
  14. 8[label="<f0> | <f1> 8 | <f2> "];  
  15. 5:f2:se->8:f1;  
  16. node[shape=record,style=filled,color=red,fontcolor=white];  
  17. 1[label="<f0> | <f1> 1 | <f2> "];  
  18. 2:f0:sw->1:f1;  
  19. node[shape=record,style=filled,color=red,fontcolor=white];  
  20. 7[label="<f0> | <f1> 7 | <f2> "];  
  21. 8:f0:sw->7:f1;  
  22. node[shape=record,style=filled,color=black,fontcolor=white];  
  23. 15[label="<f0> | <f1> 15 | <f2> "];  
  24. 18:f0:sw->15:f1;  
  25. node[shape=record,style=filled,color=black,fontcolor=white];  
  26. 999[label="<f0> | <f1> 999 | <f2> "];  
  27. 18:f2:se->999:f1;  
  28. node[shape=record,style=filled,color=black,fontcolor=white];  
  29. 11[label="<f0> | <f1> 11 | <f2> "];  
  30. 15:f0:sw->11:f1;  
  31. node[shape=record,style=filled,color=black,fontcolor=white];  
  32. 16[label="<f0> | <f1> 16 | <f2> "];  
  33. 15:f2:se->16:f1;  
  34. node[shape=record,style=filled,color=red,fontcolor=white];  
  35. 387[label="<f0> | <f1> 387 | <f2> "];  
  36. 999:f0:sw->387:f1;  
  37. node[shape=record,style=filled,color=black,fontcolor=white];  
  38. 7662[label="<f0> | <f1> 7662 | <f2> "];  
  39. 999:f2:se->7662:f1;  
  40. node[shape=record,style=filled,color=black,fontcolor=white];  
  41. 234[label="<f0> | <f1> 234 | <f2> "];  
  42. 387:f0:sw->234:f1;  
  43. node[shape=record,style=filled,color=black,fontcolor=white];  
  44. 928[label="<f0> | <f1> 928 | <f2> "];  
  45. 387:f2:se->928:f1;  
  46. node[shape=record,style=filled,color=red,fontcolor=white];  
  47. 454[label="<f0> | <f1> 454 | <f2> "];  
  48. 928:f0:sw->454:f1;  
  49. }  
digraph G{
node[shape=record,style=filled,color=black,fontcolor=white];
9[label="<f0> | <f1> 9 | <f2> "];
node[shape=record,style=filled,color=black,fontcolor=white];
5[label="<f0> | <f1> 5 | <f2> "];
9:f0:sw->5:f1;
node[shape=record,style=filled,color=red,fontcolor=white];
18[label="<f0> | <f1> 18 | <f2> "];
9:f2:se->18:f1;
node[shape=record,style=filled,color=black,fontcolor=white];
2[label="<f0> | <f1> 2 | <f2> "];
5:f0:sw->2:f1;
node[shape=record,style=filled,color=black,fontcolor=white];
8[label="<f0> | <f1> 8 | <f2> "];
5:f2:se->8:f1;
node[shape=record,style=filled,color=red,fontcolor=white];
1[label="<f0> | <f1> 1 | <f2> "];
2:f0:sw->1:f1;
node[shape=record,style=filled,color=red,fontcolor=white];
7[label="<f0> | <f1> 7 | <f2> "];
8:f0:sw->7:f1;
node[shape=record,style=filled,color=black,fontcolor=white];
15[label="<f0> | <f1> 15 | <f2> "];
18:f0:sw->15:f1;
node[shape=record,style=filled,color=black,fontcolor=white];
999[label="<f0> | <f1> 999 | <f2> "];
18:f2:se->999:f1;
node[shape=record,style=filled,color=black,fontcolor=white];
11[label="<f0> | <f1> 11 | <f2> "];
15:f0:sw->11:f1;
node[shape=record,style=filled,color=black,fontcolor=white];
16[label="<f0> | <f1> 16 | <f2> "];
15:f2:se->16:f1;
node[shape=record,style=filled,color=red,fontcolor=white];
387[label="<f0> | <f1> 387 | <f2> "];
999:f0:sw->387:f1;
node[shape=record,style=filled,color=black,fontcolor=white];
7662[label="<f0> | <f1> 7662 | <f2> "];
999:f2:se->7662:f1;
node[shape=record,style=filled,color=black,fontcolor=white];
234[label="<f0> | <f1> 234 | <f2> "];
387:f0:sw->234:f1;
node[shape=record,style=filled,color=black,fontcolor=white];
928[label="<f0> | <f1> 928 | <f2> "];
387:f2:se->928:f1;
node[shape=record,style=filled,color=red,fontcolor=white];
454[label="<f0> | <f1> 454 | <f2> "];
928:f0:sw->454:f1;
}





转载自:http://blog.csdn.net/hackooo/article/details/10564049

参考:http://blog.chinaunix.net/uid-24774106-id-3506024.html


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值