【2013微软校招面试题】输出节点数为n的二叉树的所有形态
2012-12-28 21:20
567 查看
/*
* 题意,求节点数为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
*/
代码如下所示:
* 题意,求节点数为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 ; //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的二叉树的所有形态
- 【2013微软校招面试题】求给定的一个字符串最小需要添加多少个字符才能成为回文串
- 输出1到N之间所有相加等于M的数字组合(背包问题)求相加为M的所有组合--微软酷派经典面试题
- 微软等数据结构+算法面试100题(21)--二叉树打印到叶子节点的所有路径
- 7-4 输出一棵给定二叉树的所有叶子节点
- 【2013微软校招面试题】将链表的奇偶位交换,不能使用交换链表中的值这种做法。
- 【2013微软校招面试题】设计一个栈,当栈满时,新入栈的元素循环回第一个元素的位置将其覆盖
- 9. 微软面试题:求二叉树中节点间最大距离
- 二叉树基本操作(输出所有叶子节点到根节点的路径)
- 7-8 输出二叉树中值为x的节点的所有祖先
- 每天一道LeetCode-----以字符串的形式输出二叉树所有从根节点到叶子节点的路径
- 微软,Google面试题 (4) —— 在二叉树中找出和为某一值的所有路径
- Unique Binary Search Trees II 输出二叉树的所有组合@LeetCode
- 算法与数据结构面试题(11)-求二叉树中节点的最大距离
- 解析xml文件,遍历输出xml文件中的所有节点, 最终模仿实现struts2框架
- 面试题58:二叉树的下一个节点
- PAT树_层序遍历叶节点、中序建树后序输出、AVL树的根、二叉树路径存在性判定、奇妙的完全二叉搜索树、最小堆路径、文件路由
- leetcode Sum Root to Leaf Numbers 二叉树所有叶节点的路径和
- 输出二叉树中第m层的第k个节点值
- 微软等数据结构+算法面试100题(36)-- 打印二叉树中某一层的节点