遍历n个节点能够形成的所有二叉树

帮师兄做的一个问题,就是求对n个不同节点能够形成所有的二叉树的形式,不考虑旋转对称性和同构。

问题描述:给定n个节点,查看能够有多少种不同的二叉树形成,并输出出来

算法描述:使用最基本的“分治法“(Divide and Conquer)思想,任选一个节点作为根节点,将剩余节点组成的集合进行分割(Partition),一部分放到左子树进行递归,另一部分放到右子树递归。重点为两部分:一部分使用二进制对集合进行分割,其实就是就集合的”幂集“,另一部分是如何存储。另外还可以进行暴力搜索。

测试用例:n=3,能够形成30种不同二叉树。

代码:

 1 #include <iostream>
 2 #include <string>
 3 #include <vector>
 4 using namespace std;
 5
 6 vector< string > generate_tree(const vector< string > &nodes) {
 7     if (nodes.empty()) {
 8         return vector< string >{"*"};
 9     } else if (1 == nodes.size()) {
10         return vector< string >{nodes[0]};
11     }
12     vector< string > trees, tmp, left, right, l_tree, r_tree;
13     for (size_t i = 0; i < nodes.size(); ++i) {
14         tmp = nodes;
15         tmp.erase(tmp.begin() + i);
16         for (size_t j = 0; j < 1<<tmp.size(); ++j) {  // do set partition
17             left.clear();
18             right.clear();
19             for (size_t k = 0; k < tmp.size(); ++ k) {
20                 if (!(j & (1<<k))) {
21                     left.push_back(tmp[k]);
22                 } else {
23                     right.push_back(tmp[k]);
24                 }
25             }
26             l_tree = generate_tree(left);
27             r_tree = generate_tree(right);
28             for (const string &l : l_tree) {
29                 for (const string &r : r_tree) {
30                     trees.push_back(nodes[i] + "(" + l + "," + r + ")");
31                 }
32             }
33         }
34     }
35     return trees;
36 }
37
38 int main() {
39     vector< string > nodes{"A", "B", "C"};
40     vector< string > trees = generate_tree(nodes);
41     cout << trees.size() << endl;
42     for (auto &i : trees) {
43         cout << i << endl;
44     }
45     return 0;
46 }

由于使用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种

时间: 2024-11-03 18:00:24

遍历n个节点能够形成的所有二叉树的相关文章

java 遍历所有子节点

? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86

输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。

问题描述: 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回. 思路: 在二叉树的前序遍历序列中,第一个数字总是树的根结点的值.但在中序遍历序列中,根结点的值在序列的中间,左子树的结点的值位于根结点的值的左边,而右子树的结点的值位于根结点的值的右边.因此我们需要扫描中序遍历序列,才能找到根结点的值. 如下图所示,

题目:输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树

问题描述: 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回. 思路: 在二叉树的前序遍历序列中,第一个数字总是树的根结点的值.但在中序遍历序列中,根结点的值在序列的中间,左子树的结点的值位于根结点的值的左边,而右子树的结点的值位于根结点的值的右边.因此我们需要扫描中序遍历序列,才能找到根结点的值. 如下图所示,

N4-某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。

题目描述 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回. //本题思路参考另一个大神写的代码 其原地址为:https://www.nowcoder.com/profile/566744/codeBookDetail?submissionId=1516321 /** * 输入某二叉树的前序遍历和中序遍历的结果,

二叉树基本操作--创建,三种遍历,叶子节点

虽然二叉树的操作很常见,但是认真写写熟悉很重要,特别是typedef, CreateBiTree(BiTNode** T)指针的操作等等,还有就是创建方法,去实际输入值就知道其中的妙处,为-1时为空节点. #include <iostream> using namespace std; //节点的定义 typedef struct BTNode { int data; BTNode* rChild; BTNode* lChild; }BiTNode, *BiTree; //二叉树的创建,先序创

二叉树的建立、遍历、叶子节点计数、深度计算

直接上代码,有空解释 注意这种建树方式为先序建立 sampleinput ABD*F***CE*** 输出 先序遍历结果ABDFCE中序遍历结果DFBAEC后序遍历结果FDBECA树的深度为4叶节点个数为2 #include <string.h> #include <stdlib.h> #include <stdio.h> #include <malloc.h> #include <iostream> using namespace std; s

ORACLE 树形遍历查询根节点、父节点、子节点

1.准备演示数据 创建表结构: -- Create table createtable Z_ORG(  cid         NUMBER,  cname       VARCHAR2(32),  parent_id   NUMBER,  create_time DATE,  org_level   NUMBER) tablespace POWERDESK pctfree10 initrans1 maxtrans255; -- Add comments to the table comment

关于二叉树,建立、遍历、求节点最大距离

今天做了一题求二叉树节点的最大距离,顺便写了下二叉树的建立,遍历的过程. 我觉得这题的主要思想是深度遍历+动态规划,我们在深度遍历的过程中,对于某一个子树,求出左右子树叶子节点到根节点的最大距离,进而求出经过根节点的最大距离. 最后求出所有子树经过根节点的最大距离.就是这个题目的最终结果.代码如下: //二叉树的建立,以及遍历 //16 14 8 2 -1 -1 4 -1 -1 7 1 -1 -1 -1 10 9 -1 -1 3 -1 -1 //16 14 8 2 -1 -1 4 -1 -1 7

二叉树的层序遍历、二叉树叶节点输出算法、求二叉树的高度、层序创建一棵二叉树

二叉树的层序遍历 1 void LevelorderTraversal(BinTree BT) 2 { 3 std::queue<BinTree> Queue; 4 BinTree T; 5 if (!BT) 6 return; //若是空树则直接返回 7 Queue.push(BT); 8 while (!Queue.empty()) 9 { 10 T = Queue.front(); 11 Queue.pop(); 12 printf("%c ", T->Data