九度OJ 1009 二叉搜索树

原题地址:

http://ac.jobdu.com/problem.php?pid=1009

题意:判断两输入序列是否为同一棵二叉搜索树序列。

解题思路

复习一下

  1. 二叉搜索树(BST)的定义:对于树上的任意一个节点,其上的数值必大于等于其左子树上任意节点的数值,必小于等于其右子树上任意节点的数值。即左子树<=根<=右子树
  2. 二叉搜索树的建立:通过每次向树中插入数字x来构造这棵树,如果当前树根为空,则x为根节点;若x小于当前节点,则x插入其左子树,若x大于当前节点,则x插入其右子树,若x等于当前节点,视题目要求选择向左向右或者直接忽略。
  3. 由于各个数字的插入顺序不同,得到的BST的形态很可能不同,但是所有的BST都有一个共同特点:中序遍历的结果必然是一个递增序列(所以也叫二叉排序树)。

对于这道题来说,判断两棵二叉树是否相同,我们不能简单地用中序遍历的结果来看(上面第3点),所以还需要额外一种遍历方式。包括中序遍历在内的两种遍历结果可以唯一地确定一棵二叉树。

因此我们先从输入序列构造两棵BST,再做前序、中序遍历,比较这两次遍历的结果是否相同,来判断两输入序列是否为同一棵二叉搜索树序列。

AC代码如下

#include <iostream>
#include <algorithm>
#include <string>
#include <cstring>
using namespace std;

typedef struct node
{
    char c;
    node *lchild, *rchild;
}NODE;

string str1, str2, strTemp; //str1/2存两棵树的遍历结果,strTemp用于在递归中产生序列

void preOrder(NODE* t) //前序遍历
{
    if (t != NULL)
    {
        strTemp += t->c;
        preOrder(t->lchild);
        preOrder(t->rchild);
    }
}

void midOrder(NODE* t) //中序遍历
{
    if (t != NULL)
    {
        midOrder(t->lchild);
        strTemp += t->c;
        midOrder(t->rchild);
    }
}

NODE* Insert(NODE* root, char x) //向二叉搜索树中插入节点
{
    if (root == NULL)
    {
        root = (NODE*)malloc(sizeof(NODE));
        root->c = x;
        root->lchild = root->rchild = NULL;
    }
    else if (x < root->c)
        root->lchild = Insert(root->lchild, x);
    else if (x > root->c)
        root->rchild = Insert(root->rchild, x);
    return root;
}

NODE* BuildTree(char* str)
{
    NODE* root = NULL;
    for (int i = 0; i<strlen(str); ++i) //构造比较的基准树
        root = Insert(root, str[i]);
    return root;
}

int main()
{
    int n;
    char base[15];
    char newStr[15];
    while (cin >> n)
    {
        if (n == 0) break;
        cin >> base;
        NODE* baseRoot = NULL;
        baseRoot = BuildTree(base); //构造需要被比较的基准二叉树
        for (int i = 0; i<n; ++i)
        {
            str1 = ""; str2 = ""; strTemp = "";
            cin >> newStr;
            NODE* cmpRoot = NULL;
            cmpRoot = BuildTree(newStr); //构造需要比较的新二叉树

            //检查前序序列
            preOrder(baseRoot); str1 = strTemp; strTemp = "";
            preOrder(cmpRoot);  str2 = strTemp; strTemp = "";
            if (str1 != str2)
            {
                cout << "NO" << endl;
                continue;
            }
            //检查中序序列
            midOrder(baseRoot); str1 = strTemp; strTemp = "";
            midOrder(cmpRoot);  str2 = strTemp; strTemp = "";
            if (str1 != str2)
                cout << "NO" << endl;
            else cout << "YES" << endl; //前序、中序都相同则通过比较
        }
    }
    return 0;
}

内存占用:1520Kb 耗时:0ms
算法复杂度:O(n)

posted @ 2017-03-26 22:59  Lecholin  阅读(164)  评论(0编辑  收藏  举报