二叉查找树 POJ Falling Leaves

原题描述(我的翻译版):
这里写图片描述
图1显示了字母二叉树的图形表示。熟悉字母二叉树概念的人可以跳过接下来的定义,切入正题。
字母二叉树满足下面两条之一:
1. 它可以是空树,
2. 它可以有一个根节点,该节点以;一个字母作为数据并且指向左子树和右子树。左子树和右子树也是字母二叉树。
在字母二叉树的图形表示中:
1. 空树完全省略
2. 每一个节点都代表:
一个字母,
左子树不为空将该节点和左子树相连,
右子树不为空将该节点和右子树相连,
叶子节点就是左右子树为空的节点。图1中的B, D, H, P和Y为叶子节点。
问题:
在字母二叉查找树上考虑以下操作顺序:
删除叶子节点,并列出数据删除,
重复这个过程直到树为空,
从树的左下方开始,我们产生树的显示序列,然后通过删除数据的叶子节点使得树为空。

节点删除如下:
BDHPY
CM
GQ
K
给个图:
这里写图片描述
你的问题是通过这些序列,输出原树的先序遍历。
输入:
输入将包含一个或多个数据集。每个数据集是一行或多行大写字母的序列。
该行包含在上述阶段中从二叉搜索树中移除的叶子节点。一行的字母将按字母顺序排列。数据集是由一行只有一个星号(“*”)分离。
最后一个数据集后面是一行只包含一个美元的符号($)。输入中没有空格或空行。
输出:
对于每个输入数据集,有一个唯一的二叉搜索树对应产生的叶子节点的序列。输出一行即那棵树的先序遍历,不能有空格。
输入样例:
BDHPY
CM
GQ
K
*
AC
B

$
输出样例:
KGCBDHQMPY
BAC
大意是让我们对每一个数据集建立一个二叉树,这个二叉树是很特殊的,它是一个二叉查找树(观察左右子树与根结点的关系,左子树比其小,右子树大),所以我们不难写出代码,这个题是一道二叉查找树的基础例题。
代码如下:

#include<cstdio>
#include<string>
#include<queue>
#include<iostream>
using namespace std;
struct node{
    char data;
    node* lch;
    node* rch;
}*root;
void insert(node *&root,char x)
{
    if(root==NULL) 
    {
        root=new node;
        root->data=x;
        root->lch=NULL;//一定要对左右子树赋初值NULL 
        root->rch=NULL;
        return;
    }
    if(root->data==x) return;
    else
    {
        if(x-'A'>root->data-'A')
        {
            insert(root->rch,x);
        }
        if(x-'A'<root->data-'A')
        {
            insert(root->lch,x);
        }
    }
}
void fir(node *root)
{
    if(root==NULL) return;
    else
    {
        printf("%c",root->data);
        fir(root->lch);
        fir(root->rch);
    }
}
int main()
{
    string str,s;
    int i,len;
    node *root=NULL;
  while(1)
 {
   while(cin>>s&&s!="*"&&s!="$")
   {
   str=str+s;//string这个库函数有合并两个字符串的功能,这里对一个数据集全部合并成一个串。
   } 
        len=str.length();
        for(i=len-1;i>=0;i--)//注意是倒序 
            insert(root,str[i]);
        fir(root);
        if(s=="$")
            break;
        root=NULL;//还原初始值来读入下一个 
        str.erase();
        printf("\n");
 }
  return 0;
 }



  • 5
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值