zoukankan      html  css  js  c++  java
  • 题解 P1030 【求先序排列】

    题解 P1030 【求先序排列】

    旧题新解~

    今天做这个题,发现还是没有AC,于是滚回来用了一大堆数据结构A了这个题目,好像复杂度还挺高......

    #include <iostream>
    #include <cstdio>
    #include <stack>
    #include <cstring>
    #include <map>
    #include <algorithm>
    
    using namespace std;
    char mid[101],late[101];
    int mid_[101],late_[101],len=0;
    struct tree{
    	tree *lson,*rson;
    	int ch;
    }rt_,*rt=&rt_;
    map<int,char>ic;
    map<char,int>ci;
    stack<char>qwq;
    
    void build(int ch,tree *root);
    inline void clear_(tree *root);
    void print1(tree *root);
    
    int main()
    {
    	clear_(rt);
    	scanf("%s%s",mid,late);
    	len=strlen(mid);
    	for (register int i=0;i<len;i++)
    	{
    		ic.insert(make_pair(i+1,mid[i]));
    		ci.insert(make_pair(mid[i],i+1));
    	}
    	for (register int i=0;i<len;i++)
    	{
    		late_[i]=ci[late[i]];
    	}
    	reverse(late_,late_+len);
    	for (register int i=0;i<len;i++)
    	{
    		build(late_[i],rt);
    	}
    	print1(rt);
    	while (!qwq.empty())
    	{
    		putchar(qwq.top());
    		qwq.pop();
    	}
    	return 0;
    }
    void build(int ch,tree *root)
    {
    	if (root->ch==-1||root->ch==ch)//相等或者是新的节点 
    	{
    		root->ch=ch;//直接赋值不多说 
    		return ;
    	}
    	else if (root->ch<ch)//小于建左树 
    	{
    		if (root->lson==NULL)//如果没开点就开点 
    		{
    			root->lson=new tree();
    			clear_(root->lson);
    		}
    		build(ch,root->lson);//递归建左子树 
    	}
    	else //那就只剩下大于咯
    	{
    		if (root->rson==NULL)//如果没开点就开点 
    		{
    			root->rson=new tree();
    			clear_(root->rson);
    		}
    		build(ch,root->rson);//递归建右子树 
    	} 
    }
    inline void clear_(tree *root)
    {
    	root->lson=root->rson=NULL;
    	root->ch=-1;
    }
    void print1(tree *root)//先序排列 
    {
    	if (root->lson!=NULL)print1(root->lson);
    	if (root->rson!=NULL)print1(root->rson);
    	qwq.push(ic[root->ch]);
    }
    

    看看这一长串代码,令人生畏......

    首先把题目摆上......

    题目描述

    给出一棵二叉树的中序与后序排列。求出它的先序排列。(约定树结点用不同的大写字母表示,长度(n≤8))。

    输入输出格式

    输入格式:

    2行,均为大写字母组成的字符串,表示一棵二叉树的中序与后序排列。

    输出格式:

    11行,表示一棵二叉树的先序。

    输入输出样例

    输入样例#1: 输出样例#1:
    BADC
    BDCA
    ABCD

    拿过来一看,不就是模拟吗!

    但是我们将原先的中序和后序都离散化成二叉搜索树(闲得慌????),就变得好理解了许多(中规中蒟)

    原文作者说:

    因为对于二叉搜索树左小右大的原则,其中序遍历即为树中的元素的升序排列。而后序遍历是按先左子右子再根节点的顺序输出

    因此 对于二叉搜索树而言——

    如果按照其后序遍历的颠倒后的顺序插入元素,就可以还原整棵树

    原因是在元素x被插入以前,x的父节点已经插入在树中(后序遍历的颠倒后的顺序),因此x一定会插入到原来的树中的位置上。

    原来如果我们按照颠倒的后序遍历建一个二叉搜索树,然后将输出的字符串存入stack<char>,然后再倒着输出,就完成先序遍历的操作。

    感觉有点迷?不要紧,还有一发。

    Q1:为什么要颠倒插入?

    A:因为后序遍历就是离散化后的从大到小的排序,所以我们将其反转,就可以得到一个先序遍历。按照先序遍历,可以还原整棵树。

    Q2:为什么最后要颠倒输出?

    因为我们得到的是先序遍历的离散化数据,所以答案反而是逆序的字母串。

    Clear?

  • 相关阅读:
    TestNG入门教程-6-enabled和priority属性
    TestNG入门教程-5-timeOut属性
    TestNG入门教程-4-Testng中注释简介
    Unicode、UTF-8 和 ISO8859-1到底有什么区别
    java数目
    sql必知必会-总结篇
    mysql监控、性能调优及三范式理解
    loadrunner常用函数总结
    loadrunner监控度量项及中文解释
    linux下crontab的使用实现
  • 原文地址:https://www.cnblogs.com/jelly123/p/10632179.html
Copyright © 2011-2022 走看看