`
xinjiang
  • 浏览: 55584 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

NOJ 1848--二叉树

阅读更多

题目来源:http://acm.nuc.edu.cn/OJ/problem.php?pid=1848

Description:

对于一颗二叉树,当给定前序遍历和中序遍历,那么后序遍历必定是确定的,但是如果只给定前序遍历和中序遍历时,中序遍历是不定的。例如,前序遍历为ABCD,后序遍历为CBDA,那么中序遍历有CBAD和BCAD两种。 现在的问题就是给定前序和后序遍历序列,要求出总共有多少棵不同形态的二叉树满足这样的遍历顺序。

Input:

整个输入有两行,第一行给出前序遍历的访问顺序,第二行给定后序比那里的访问顺序,二叉树节点用一个大写字母表示,不会有两个节点标上相同的字母。输入数据不包含空格,且保证至少有一棵二叉树满足要求。

Output:

输出一个整数,表示符合要求的不同形态二叉树的数目。

Example Input:

ABCD
CBDA

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题

    在“西北工业大学数据结构noj_1-6题”中,我们可以推测这是一系列与数据结构相关的编程练习题目,旨在帮助学生理解和应用各种数据结构。以下是基于这些题目可能涵盖的一些关键知识点的详细解释: 1. **线性数据结构...

    西北工业大学 NOJ 部分难题题解

    2. **数据结构**:如链表、栈、队列、树(二叉树、平衡树如AVL和红黑树)、图、哈希表和堆等。在解题过程中,选择合适的数据结构能显著提高算法效率。 3. **字符串处理**:涉及到模式匹配(KMP、Boyer-Moore算法)...

    南京邮电大学数据结构课程部分实验.zip

    - 实验四 NOJ1061.c、NOJ1062.c、NOJ1063.c、NOJ1064.c 和 NOJ1065.c:这些实验很可能涵盖了不同的排序算法(如冒泡排序、插入排序、选择排序、快速排序、归并排序等)和查找算法(如顺序查找、二分查找、哈希查找...

    西工大c语言poj答案

    2. **图论与树**:最小生成树、拓扑排序、二叉树遍历等。 3. **动态规划**:背包问题、最长公共子序列、最短路径问题等。 4. **递推与回溯**:斐波那契数列、八皇后问题、深度优先搜索等。 5. **字符串处理**:...

    西北工业大学数据结构及实验答案.7z

    二叉树、平衡树(如AVL树、红黑树)和堆(最大堆、最小堆)是常见的树型数据结构。 6. **图**:由顶点和边构成,用于表示各种关系,如网络拓扑、社交关系等。图可以是无向的,也可以是有向的,还可以带有权重。 7....

    数据结构 顺序表 删除

    在实际应用中,根据数据规模和需求,可能会选择链表、动态数组(如Java的ArrayList)或其他更复杂的数据结构,如二叉树、哈希表等,来替代简单的顺序表。 总之,顺序表作为基本的数据结构,对理解计算机科学中的...

    西北工业大学数据结构试题

    4. **树**:树形结构模拟了自然界中的层次关系,如二叉树、平衡二叉树(AVL树、红黑树)、B树、B+树等。二叉树的操作包括查找、插入、删除,而平衡树则关注如何保持平衡以保证操作效率。 5. **图**:图由顶点和边...

    西工大最新poj答案 2014年新整理

    3. **数据结构**:数组、链表、栈、队列、树(二叉树、平衡树如AVL和红黑树)、图、哈希表等。 4. **动态规划**:通过状态转移方程求解最优化问题。 5. **贪心算法**:局部最优解策略来求全局最优解。 6. **回溯...

    数据结构实验考试.zip

    这些资源可以帮助你更好地可视化数据结构,比如二叉树的遍历、图的拓扑排序等,同时也能提供示例数据来测试你的程序。 总的来说,这个压缩包提供了一个全面的学习和实践环境,让你能深入理解数据结构,掌握其应用,...

    ACM_Code_包括计算几何.特殊数据结构.组合数学等知识点的代码.每个代码对应一道ACM试题,根据代码头说明找到

    - **树**:树是数据结构的一种,ACM中的树问题可能涉及到二叉树、树的遍历、树的重构等。 - **变治法**和**输入问题**:通常与I/O效率和优化有关,例如快速读入、预处理输入数据等。 - **竞赛**:ACM竞赛中的策略...

    ACMer 必知必会(入门必看)

    数据结构如栈、队列、链表、树(二叉树、平衡树)和哈希表等,是实现高效算法的基石。理解这些理论知识,并能灵活运用到实际问题中,是提升编程能力的关键。 **练级篇:实践** 理论与实践相结合才能更好地提升技能...

Global site tag (gtag.js) - Google Analytics