九度OJ 1009 二叉搜索树
原题地址:
http://ac.jobdu.com/problem.php?pid=1009
题意:判断两输入序列是否为同一棵二叉搜索树序列。
解题思路
复习一下
- 二叉搜索树(BST)的定义:对于树上的任意一个节点,其上的数值必大于等于其左子树上任意节点的数值,必小于等于其右子树上任意节点的数值。即左子树<=根<=右子树。
- 二叉搜索树的建立:通过每次向树中插入数字x来构造这棵树,如果当前树根为空,则x为根节点;若x小于当前节点,则x插入其左子树,若x大于当前节点,则x插入其右子树,若x等于当前节点,视题目要求选择向左向右或者直接忽略。
- 由于各个数字的插入顺序不同,得到的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)