【2013微软面试题】输出节点数为n的二叉树的所有形态
转自:http://blog.csdn.net/monsterxd/article/details/8449005
/*
* 题意,求节点数为n的二叉树的所有形态,先要想个方式来唯一标示一棵二叉树
*
* 方法一:一个前序+一个中序,可以还原一棵唯一的二叉树,故使用【前序输出的字符串+中序输出的字符串】
* 来唯一标示一棵二叉树。
*
* 方法二:【将一颗二叉树逐层遍历,若节点不为空,则记为X,为空记为O,最终得到的序列可以唯一标示一颗二叉树。】
*
* 建树过程采用递归,对已经建成的树的部分,每次节点逐一判断其左右儿子是否可以插入,可以的话,则插入,然后递归。
* 直到数的大小达到n,则记录这棵树的唯一标示,然后返回!
*
* output: 例如输入3,
* 则输出结果,对应的二叉树如下所示:
* X X X X X
* X O X O O X O X X X
* X O O X X O O X O O O O
* O O O O O O O O
*/
代码如下所示:
#include <iostream>
#include <string>
#include <map>
#include <vector>
using namespace std; int n; //二叉树有n个节点
map<string, int> m; struct Node{
Node * left;
Node * right;
}; void PreOut(Node * head, string &s) //先序输出,根左右
{
s += "X"; //根
if(head->left != NULL) //左
PreOut(head->left, s);
else
s += "O";
if(head->right != NULL) //右
PreOut(head->right, s);
else
s += "O";
} void MidOut(Node * head, string &s) //中序输出,左根右
{
if(head->left != NULL) //左
MidOut(head->left, s);
else
s += "O";
s += "X";
if(head->right != NULL) //右
MidOut(head->right, s);
else
s += "O"; } //逐层遍历二叉树
void Bfs(Node * head, string &s)
{
vector<Node *> vec;
vec.push_back(head);
for(int i=0; i<vec.size(); i++)
{
if(vec[i] != NULL)
{
s += "X";
vec.push_back(vec[i]->left); //左儿子入队,为NULL的时候也入队
vec.push_back(vec[i]->right); //右儿子入队
}
else
s += "O";
}
} /*
* head: 为整棵树的根节点
* arr: 为二叉树节点的数组
* now: 为当前已经建立的树的节点数
* total:为输入n,总共的节点数
* 建树时间复杂度: 卡特兰数复杂度 C(2*n,n)/(n+1)
*/
void BuildAllKindsTree(Node * head, Node * arr, int now, int total)
{
if(now == total) //成功建立一棵树
{
string s = "";
//PreOut(head, s);
//MidOut(head, s);
Bfs(head, s);
m[s]++;
return;
} for(int i=0; i<now; ++i) //当前建立的树已经有 now 个节点
{
if( arr[total - 1 - i].left == NULL ) //该节点左儿子位置可以链接个节点
{
arr[total - 1 - i].left = &arr[total - 1 - now];
BuildAllKindsTree(head, arr, now+1, total);
arr[total - 1 - i].left = NULL; //递归回溯
}
if( arr[total - 1 - i].right == NULL) //该节点右儿子位置可以链接个节点
{
arr[total - 1 - i].right = &arr[total - 1 - now];
BuildAllKindsTree(head, arr, now+1, total);
arr[total - 1 - i].right = NULL;
}
}
} void output()
{
cout<<"*****************************************************************"<<endl;
map<string, int>::iterator iter = m.begin();
for(; iter != m.end(); iter++)
cout<<iter->first<<endl;
cout<<n<<"个节点的时候,二叉树总共有"<<m.size()<<"种情况。"<<endl;
cout<<"*****************************************************************"<<endl;
} int main()
{
while(cin>>n)
{
m.clear();
Node * a = new Node[n]; //new出n个节点
for(int i=0; i<n; i++)
{
a[i].left = NULL;
a[i].right = NULL;
} BuildAllKindsTree(&a[n-1], a, 1, n); output();
delete []a;
}
}
【2013微软面试题】输出节点数为n的二叉树的所有形态的更多相关文章
- Java实现二叉搜索树的添加,前序、后序、中序及层序遍历,求树的节点数,求树的最大值、最小值,查找等操作
什么也不说了,直接上代码. 首先是节点类,大家都懂得 /** * 二叉树的节点类 * * @author HeYufan * * @param <T> */ class Node<T ...
- 求二叉树第n层节点数
在知乎看到今日头条的一个面试题“求二叉树第n层节点数”:https://zhuanlan.zhihu.com/p/25671699,想到了这样一个解法,欢迎大家交流 我的解法采用递归的思想,从0层开始 ...
- 1094. The Largest Generation (25)-(dfs,树的遍历,统计每层的节点数)
题目很简单,就是统计一下每层的节点数,输出节点数最多的个数和对应的层数即可. #include <iostream> #include <cstdio> #include &l ...
- Spark中Task,Partition,RDD、节点数、Executor数、core数目的关系和Application,Driver,Job,Task,Stage理解
梳理一下Spark中关于并发度涉及的几个概念File,Block,Split,Task,Partition,RDD以及节点数.Executor数.core数目的关系. 输入可能以多个文件的形式存储在H ...
- Spark中Task,Partition,RDD、节点数、Executor数、core数目(线程池)、mem数
Spark中Task,Partition,RDD.节点数.Executor数.core数目的关系和Application,Driver,Job,Task,Stage理解 from:https://bl ...
- 确定BP神经网络中的节点数
输入层 输入层节点数=输入向量维数 MNIST例子中,单张MNIST图片大小为28*28,reshape为一维数组,长度为784,所以输入层节点数为784: network = Network([78 ...
- 每日微软面试题——day 6(打印所有对称子串)
每日微软面试题——day 6(打印所有对称子串) 分类: 2.数据结构与算法2011-08-14 14:27 9595人阅读 评论(15) 收藏 举报 面试微软string测试systemdistan ...
- 【剑指Offer面试题】 九度OJ1385:重建二叉树
题目链接地址: pid=1385">http://ac.jobdu.com/problem.php?pid=1385 题目1385:重建二叉树 时间限制:1 秒内存限制:32 兆特殊判 ...
- hiho一下 第一百零七周 Give My Text Back(微软笔试题)
题目1 : Give My Text Back 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 To prepare for the English exam Littl ...
随机推荐
- json 得到时分秒为00:00:00,拿不到时分秒 解决办法
数据库查询时间没有了时分秒的解决办法 问题出处,公司一个项目中使用动态sql方式查询Oracle数据库,在展示时Date类型字段只展示日期,无时分秒. 分析: ...
- poj 1180 斜率优化dp
这个题目要是顺着dp的话很难做,但是倒着推就很容易退出比较简单的关系式了. dp[i]=min(dp[u]+(sum[u-1]-sum[i-1]+s)*f[i]);dp[i]代表从i到结尾需要花费的代 ...
- 【CCS仿真】用matlab把CCS保存的32位16进制的数据转换为十进制的数
2013-12-04 16:37:28 使用fscanf函数即可完成. 例如,CCS保存的.dat文件Copy_of_forward_i_f.dat如下: 1651 1 81008800 0 4000 ...
- Uubuntu 14.04 LTS反编译apk
使用apktool反编译apk 1.安装apktool apktool是Google提供的APK编译工具,能够反编译及回编译apk,需要Java环境的支持(在此不再赘述Java的安装与配置,详见< ...
- 下拉刷新控件(4)SwipeRefreshLayout官方教程(上)如何在应用中使用它
http://developer.android.com/training/swipe/add-swipe-interface.html 1,在布局xml和代码中使用它 2,在menu中添加它 The ...
- 《OD学hadoop》第三周0709
一.MapReduce编程模型1. 中心思想: 分而治之2. map(映射)3. 分布式计算模型,处理海量数据4. 一个简单的MR程序需要制定map().reduce().input.output5. ...
- cdoj 1329 卿学姐与魔法 优先队列
卿学姐与魔法 Time Limit: 1200/800MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others) Submit Sta ...
- Oracle数据库之一
数据库(oracle) SQL --结构化查询语言,所有数据库基本通用 数据库是数据的仓库,用于存储数据. 内存.文件和数据库区别 内存中的数据是非持久的,关机之后就会消失. 文件和数据库中的数据都是 ...
- 51nod1421 最大MOD值
O(n2)tle.O(nlognlogn) #include<cstdio> #include<cstring> #include<cctype> #include ...
- BZOJ 2303 方格染色
首先考虑四个格子异或值为1. 然后(重点)发现每个格子的值只和最上面,最左边,和(1,1)的格子的颜色有关. 枚举(1,1)的颜色,联立方程,可以将未知数减少,那么并查集可做. 最后算答案的时候,有些 ...