题目来源:http://acm.nuc.edu.cn/OJ/problem.php?pid=1848
Description:
对于一颗二叉树,当给定前序遍历和中序遍历,那么后序遍历必定是确定的,但是如果只给定前序遍历和中序遍历时,中序遍历是不定的。例如,前序遍历为ABCD,后序遍历为CBDA,那么中序遍历有CBAD和BCAD两种。
现在的问题就是给定前序和后序遍历序列,要求出总共有多少棵不同形态的二叉树满足这样的遍历顺序。
Input:
整个输入有两行,第一行给出前序遍历的访问顺序,第二行给定后序比那里的访问顺序,二叉树节点用一个大写字母表示,不会有两个节点标上相同的字母。输入数据不包含空格,且保证至少有一棵二叉树满足要求。
Output:
输出一个整数,表示符合要求的不同形态二叉树的数目。
Example Input:
Example Output:
2
首先对例子进行分析
/****真是悲哀,不知道怎么插入图片,只能通过上传图片的方式**/
(1)
前序遍历和后序遍历的最后一个字母必定是根,即都是
A
(2)
前序遍历的第二个字母是
B
也必定是某颗子树的根(左右无法确定)。那么
B
在后序遍历中一定出现在它所在子树的最后,因此我们可以通过查找
B
在后序遍历中的位置来得到左子树的所有节点,即为
B
和
C
,剩下的
D
就是右子树的节点了
(3)
分别用同样的方法分析左子树
BC
及右子树
D
,
D
只有一个根,形态是唯一的,
BC
只有一颗子树,它可以是左也可以是右
(4)
最后看看有多少个节点(假设是
n
)是只有一颗子树的,用乘法
pow
(
2
,
n
)就是结果
下面推广到所有的二叉树:
首先我们需要设几个变量:
PreStr[100];
//
前序遍历的数组
PostStr[100];
//
后序遍历的数组
Length
;
//
数组的长度
Count;
//
记录只有一个子树的节点的个数
(1)
如果
Length == 1
,显然结果唯一
(2)
当顶点多余
1
时,说明存在子树,必然有
PreStr[0]==PostStr[Length-1];
如果
PreStr[1] == PostStr[Length-2];
说明从
1
到
Length-1
都是
PreStr[0]
的子树,至于是左还是右就无法确定,此时
Count++
。对剩下的
PreStr[1]
到
PreStr[Length-1]
与
PostStr[0]
到
PostStr[Length-2]
作为一颗新树进行处理
(3)
如果
PreStr[1]
!= PostStr[Length-2],
显然存在左右子树
(PostStr
中以与
PreStr[1]
相等的位置分为左右子树
)
,对左右子树分别作为一颗独立的子树进行处理
#include <stdio.h>
#include <string.h>
char PreStr[30]; //前序遍历的字符串
char PostStr[30]; //后序遍历的字符串
int count; //记录只有一个子树的节点的个数
void calc(int a1,int b1,int a2,int b2)
{
/*计算前序遍历a1到b1的子串,后序遍历a2到b2的子串*/
int i;
if(a1>=b1) return; //子串长度为1时不需要作出处理
for(i=a2; i<=b2-1; i++) //寻找左子树的位置
{
if(PreStr[a1+1] == PostStr[i]) break;
}
if(i == b2-1) count++; //只有一颗子树时
calc(a1+1,a1+1+(i-a2),a2,i); //处理左子树
calc(a1+1+(i-a2)+1,b1,i+1,b2-1); //处理右子树
}
int Pow(int n)
{
/*计算2的n次方*/
int i;
int m = 1;
for(i = 0; i < n; i++)
{
m *= 2;
}
return m;
}
int main()
{
int Length;
scanf("%s", PreStr);
scanf("%s", PostStr);
Length = strlen(PreStr);
count = 0;
calc(0,Length-1,0,Length-1);
printf("%d\n", Pow(count));
return 0;
}
- 大小: 11.4 KB
分享到:
相关推荐
在“西北工业大学数据结构noj_1-6题”中,我们可以推测这是一系列与数据结构相关的编程练习题目,旨在帮助学生理解和应用各种数据结构。以下是基于这些题目可能涵盖的一些关键知识点的详细解释: 1. **线性数据结构...
2. **数据结构**:如链表、栈、队列、树(二叉树、平衡树如AVL和红黑树)、图、哈希表和堆等。在解题过程中,选择合适的数据结构能显著提高算法效率。 3. **字符串处理**:涉及到模式匹配(KMP、Boyer-Moore算法)...
- 实验四 NOJ1061.c、NOJ1062.c、NOJ1063.c、NOJ1064.c 和 NOJ1065.c:这些实验很可能涵盖了不同的排序算法(如冒泡排序、插入排序、选择排序、快速排序、归并排序等)和查找算法(如顺序查找、二分查找、哈希查找...
2. **图论与树**:最小生成树、拓扑排序、二叉树遍历等。 3. **动态规划**:背包问题、最长公共子序列、最短路径问题等。 4. **递推与回溯**:斐波那契数列、八皇后问题、深度优先搜索等。 5. **字符串处理**:...
二叉树、平衡树(如AVL树、红黑树)和堆(最大堆、最小堆)是常见的树型数据结构。 6. **图**:由顶点和边构成,用于表示各种关系,如网络拓扑、社交关系等。图可以是无向的,也可以是有向的,还可以带有权重。 7....
在实际应用中,根据数据规模和需求,可能会选择链表、动态数组(如Java的ArrayList)或其他更复杂的数据结构,如二叉树、哈希表等,来替代简单的顺序表。 总之,顺序表作为基本的数据结构,对理解计算机科学中的...
4. **树**:树形结构模拟了自然界中的层次关系,如二叉树、平衡二叉树(AVL树、红黑树)、B树、B+树等。二叉树的操作包括查找、插入、删除,而平衡树则关注如何保持平衡以保证操作效率。 5. **图**:图由顶点和边...
3. **数据结构**:数组、链表、栈、队列、树(二叉树、平衡树如AVL和红黑树)、图、哈希表等。 4. **动态规划**:通过状态转移方程求解最优化问题。 5. **贪心算法**:局部最优解策略来求全局最优解。 6. **回溯...
这些资源可以帮助你更好地可视化数据结构,比如二叉树的遍历、图的拓扑排序等,同时也能提供示例数据来测试你的程序。 总的来说,这个压缩包提供了一个全面的学习和实践环境,让你能深入理解数据结构,掌握其应用,...
- **树**:树是数据结构的一种,ACM中的树问题可能涉及到二叉树、树的遍历、树的重构等。 - **变治法**和**输入问题**:通常与I/O效率和优化有关,例如快速读入、预处理输入数据等。 - **竞赛**:ACM竞赛中的策略...
数据结构如栈、队列、链表、树(二叉树、平衡树)和哈希表等,是实现高效算法的基石。理解这些理论知识,并能灵活运用到实际问题中,是提升编程能力的关键。 **练级篇:实践** 理论与实践相结合才能更好地提升技能...