遍历n个节点能够形成的所有二叉树
2016-02-23 17:01
211 查看
帮师兄做的一个问题,就是求对n个不同节点能够形成所有的二叉树的形式,不考虑旋转对称性和同构。
问题描述:给定n个节点,查看能够有多少种不同的二叉树形成,并输出出来
算法描述:使用最基本的“分治法“(Divide and Conquer)思想,任选一个节点作为根节点,将剩余节点组成的集合进行分割(Partition),一部分放到左子树进行递归,另一部分放到右子树递归。重点为两部分:一部分使用二进制对集合进行分割,其实就是就集合的”幂集“,另一部分是如何存储。另外还可以进行暴力搜索。
测试用例:n=3,能够形成30种不同二叉树。
代码:
由于使用c++11的特性,所以文件的编译命令为
输出结果为
当n=4时,有336种
当n=5时,有5040种
问题描述:给定n个节点,查看能够有多少种不同的二叉树形成,并输出出来
算法描述:使用最基本的“分治法“(Divide and Conquer)思想,任选一个节点作为根节点,将剩余节点组成的集合进行分割(Partition),一部分放到左子树进行递归,另一部分放到右子树递归。重点为两部分:一部分使用二进制对集合进行分割,其实就是就集合的”幂集“,另一部分是如何存储。另外还可以进行暴力搜索。
测试用例:n=3,能够形成30种不同二叉树。
代码:
#include <iostream> #include <string> #include <vector> using namespace std; vector< string > generate_tree(const vector< string > &nodes) { if (nodes.empty()) { return vector< string >{"*"}; } else if (1 == nodes.size()) { return vector< string >{nodes[0]}; } vector< string > trees, tmp, left, right, l_tree, r_tree; for (size_t i = 0; i < nodes.size(); ++i) { tmp = nodes; tmp.erase(tmp.begin() + i); for (size_t j = 0; j < 1<<tmp.size(); ++j) { // do set partition left.clear(); right.clear(); for (size_t k = 0; k < tmp.size(); ++ k) { if (!(j & (1<<k))) { left.push_back(tmp[k]); } else { right.push_back(tmp[k]); } } l_tree = generate_tree(left); r_tree = generate_tree(right); for (const string &l : l_tree) { for (const string &r : r_tree) { trees.push_back(nodes[i] + "(" + l + "," + r + ")"); } } } } return trees; } int main() { vector< string > nodes{"A", "B", "C"}; vector< string > trees = generate_tree(nodes); cout << trees.size() << endl; for (auto &i : trees) { cout << i << endl; } return 0; }
由于使用c++11的特性,所以文件的编译命令为
g++ -std=c++11 generate_tree.cc
输出结果为
30 A(B(C,*),*) A(B(*,C),*) A(C(B,*),*) A(C(*,B),*) A(C,B) A(B,C) A(*,B(C,*)) A(*,B(*,C)) A(*,C(B,*)) A(*,C(*,B)) B(A(C,*),*) B(A(*,C),*) B(C(A,*),*) B(C(*,A),*) B(C,A) B(A,C) B(*,A(C,*)) B(*,A(*,C)) B(*,C(A,*)) B(*,C(*,A)) C(A(B,*),*) C(A(*,B),*) C(B(A,*),*) C(B(*,A),*) C(B,A) C(A,B) C(*,A(B,*)) C(*,A(*,B)) C(*,B(A,*)) C(*,B(*,A))
当n=4时,有336种
当n=5时,有5040种
相关文章推荐
- AVL树-自平衡二叉查找树(Java实现)
- 书评:《算法之美( Algorithms to Live By )》
- 动易2006序列号破解算法公布
- 文件遍历排序函数
- Ruby实现的矩阵连乘算法
- C#插入法排序算法实例分析
- Lua 学习笔记之C API 遍历 Table实现代码
- 超大数据量存储常用数据库分表分库算法总结
- C#数据结构与算法揭秘二
- C#冒泡法排序算法实例分析
- C#遍历文件夹后上传文件夹中所有文件错误案例分析
- C#中遍历Hashtable的4种方法
- 算法练习之从String.indexOf的模拟实现开始
- C#算法之关于大牛生小牛的问题
- C#实现的算24点游戏算法实例分析
- mysql binlog二进制日志详解
- Erlang中遍历取出某个位置的最大值代码
- c语言实现的带通配符匹配算法
- 浅析STL中的常用算法
- C++实现图的邻接矩阵存储和广度、深度优先遍历实例分析