您的位置:首页 > 其它

算法,请不要这么经典 - 二叉树的可视化

2015-03-23 17:01 337 查看
围绕二叉树的算法实在是太多了,以前也总结过一些,但这次决定通过博客的方式,把自己的一些总结和大家分享一下。

首先声明,代码中肯定会参考一些别人的代码,由于是陆陆续续总结的,所以没法给出参考的链接,在此谨表示感谢,如果觉得侵犯了版权,可以给我留言。

由于二叉树相关的算法很多,所以我们将以专辑的方式讨论一下。

在讨论具体算法之前,想想要是能把二叉树打印出来多好啊,看到很多博客上都有很多的图,看起来确实很直观。

对于链表,树,图等数据结构,本身也是很适合用可视化的方法来表示的。

可视化方面的软件也有不少,以前接触过graphviz,知道它的威力,于是本专辑中将用它来画出相应的数据结构, 请先安装graphviz吧。

先上几个图先睹为快吧:

example 1: 把二叉树展开成双向链表





example 2: 把二叉树展开成单向链表





template <typename Comparable>
class BSTNode
{
public:
Comparable val;
BSTNode *left, *right;
BSTNode(Comparable v, BSTNode *l = NULL, BSTNode *r = NULL)
: val(v), left(l), right(r) {
}
};


template <typename Comparable>
void BST<Comparable>::dump_dot(const string &fileName) {
dump_dot(fileName, root);
}

template <typename Comparable>
void BST<Comparable>::dump_dot(const string &fileName, BSTNode<Comparable> *t)
{
string begin = "\
digraph G {\n \
graph [ dpi = 100 ];\n \
nodesep=0.3;\n \
ranksep=0.2;\n \
margin=0.1;\n \
node [shape=circle];\n \
edge [arrowsize=0.8];\n";

string end = "}";

ofstream ofs(fileName);
if (ofs) {
ofs << begin << endl;
ofs << dump_dot_imp(t);
ofs << end << endl;
}
ofs.close();
}
//dot tree.dot | neato -n -Tpng -o ~/Desktop/tree.png
//dot -Tpng tree.dot -O
//http://stackoverflow.com/questions/10902745/enforcing-horizontal-node-ordering-in-a-dot-tree
//http://www.graphviz.org/content/FaqBalanceTree => this method is adopted here!!!
template <typename Comparable>
string BST<Comparable>::dump_dot_imp(BSTNode<Comparable> *t)
{
string result;
if (t) {
ostringstream out;
if (t->left) out << "    " << t->val << " -> " << t->left->val << ";" << endl;
if (t->right) out << "    " << t->val << " -> " << t->right->val << ";" << endl;

// introduce new, invisible middle nodes to re-balance the layout.
{
unsigned long long addr = (unsigned long long)(unsigned*)t;
out << "    " << addr <<  " [label=\"\",width=.1,style=invis]" << endl;
out << "    " << t->val << " -> " << addr << " [style=invis]" << endl;
if (t->left || t->right) {
out << "    {rank=same ";
if (t->left) {
out << t->left->val << " -> ";
}
out << addr;
if (t->right) {
out << " -> " << t->right->val;
}
out << " [style=invis]}" << endl<<endl;
}
}

result = out.str();
// When we flatten the BST into a double linked list,
// we should not access its left again, otherwise, it will be endless.
// For single linked list, t->left == NULL.
if (t->left && t->left->right != t)
result += dump_dot_imp(t->left);
result += dump_dot_imp(t->right);
}
return result;
}


更完整的代码请参考:
https://code.csdn.net/hp_truth/data_structure_and_algorithm/tree/master/tree/bst.cpp
编译运行:

g++ bst.cpp -std=c++11; ./a.out; for i in ~/Desktop/*.dot; do dot $i | neato
-n -Tpng -o $i.png; done
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐