您的位置:首页 > 其它

HUNAN NORMAL UNIVERSITY OJ 10383 线索二叉树 胡乱yy的方法

2016-01-04 16:56 549 查看
题目:http://acm.hunnu.edu.cn/online/?action=problem&type=show&id=10383

线索二叉树
Time Limit: 1000ms, Special Time Limit:2500ms, Memory Limit:32768KB
Total submit users: 7, Accepted users: 6
Problem 10383 : No special judgement
Problem description
  线索二叉树概念

1.定义

     n个结点的二叉链表中含有n+1个空指针域。利用二叉链表中的空指针域,存放指向结点在某种遍历次序下的前趋和后继结点的指针(这种附加的指针称为"线索")。
这种加上了线索的二叉链表称为线索链表,相应的二叉树称为线索二叉树(Threaded   BinaryTree)。根据线索性质的不同,线索二叉树可分为前序线索二叉树、中序线索二叉树和后序线索二叉树三种。

  注意:

     线索链表解决了二叉链表找左、右孩子困难的问题,出现了无法直接找到该结点在某种遍历序列中的前趋和后继结点的问题。

2.线索链表的结点结构

     线索链表中的结点结构为:



   其中:

     ltag和rtag是增加的两个标志域,用来区分结点的左、右指针域是指向其左、右孩子的指针,还是指向其前趋或后继的线索。
下面你的任务:首先根据输入的序列建立二叉树,然后对二叉树进行线索化,最后中序遍历二叉线索树并输出结果。

Input
  输入的第一行包含单独的一个数字T,表示测试序列的数目; 

以下每一行为一个测试序列,测试序列是按先序序列输入字符 ,如果节点没有左或右孩子,则输入用空格表示,最后用一个空格结束一行的输入。
Output
  对应每个测试序列,采用中序遍历二叉线索树,输出一行
Sample Input
2ABC  DE G  F   -+a  *b  -c  d  /e  f

Sample Output
CBEGDFAa+b*c-d-e/f

Judge Tips
  

#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<climits>
#include<queue>
#include<vector>
#include<map>
#include<sstream>
#include<set>
#include<stack>
#include<cctype>
#include<utility>
#pragma comment(linker, "/STACK:102400000,102400000")
#define PI (4.0*atan(1.0))
#define eps 1e-10
#define sqr(x) ((x)*(x))
#define FOR0(i,n) for(int i=0 ;i<(n) ;i++)
#define FOR1(i,n) for(int i=1 ;i<=(n) ;i++)
#define FORD(i,n) for(int i=(n) ;i>=0 ;i--)
//#define lson ind<<1,le,mid
//#define rson ind<<1|1,mid+1,ri
#define MID int mid=(le+ri)>>1
#define zero(x)((x>0? x:-x)<1e-15)
#define mk make_pair
#define _f first
#define _s second
#define ysk(x) (1<<(x))
using namespace std;
//const int INF= ;
typedef long long ll;
//const ll inf =1000000000000000;//1e15;
//ifstream fin("input.txt");
//ofstream fout("output.txt");
//fin.close();
//fout.close();
//freopen("a.in","r",stdin);
//freopen("a.out","w",stdout);
const int INF =0x3f3f3f3f;
const int maxn= 1020 ;
//const int maxV=12 ;

struct INPUT
{
char s[maxn+10];
int p;
INPUT(){}
void clear(){p=0;}
char nex()
{
if(!s[p]) return s[p];
p++;
return s[p-1];
}
}input;

struct Node
{
char data;
bool ltag,rtag;
Node* lson,*rson;//Node* lson,rson;这不对!!!//此处的两个指针和build函数中的指针引用是不同的,
//此处两个指针指向同一个东西,通过一个指针调用指向的对象,可以改变对象的性质
//要是 Node *a;Node *b=a;之后b=new Node()(b改变的指向的对象),再修改b对a所指向的对象不会产生印象。
//这就是为什么底下build()函数中要用引用&
Node(){}
Node(char data):data(data) {ltag=rtag=1;lson=NULL,rson=NULL;}
}*root,*st;

Node *last;
struct Connection
{
Node* le,*ri;

Connection(){le=ri=last=NULL;}
void clear() {le=ri=last=NULL;}
void push(Node* & p)
{
le=ri;
ri=p;
last=p;
if(le&&ri)
{
le->rson=ri;
ri->lson=le;
}
}
} con;

bool prebuild(Node* &x)//这样写要加引用
{
x= new Node(input.nex());//x= & Node(input.nex());是错的
if(x->data==' '||x->data=='\0') return 1;
x->ltag=prebuild(x->lson) ;
x->rtag=prebuild(x->rson) ;
return 0;

}

void build()
{
root=NULL;
prebuild(root);
}

void dfs(Node*x)
{

if(!x->ltag) dfs(x->lson);
con.push(x);
if(!x->rtag) dfs(x->rson);
}

void findst()
{
st=root;
while(!st->ltag) st=st->lson;

}

void print()
{
Node *s=st;
while(s)//while(s)
{
printf("%c",s->data);
s=s->rson;
}
putchar('\n');
}

void de(Node *x)
{
Node* t=x->rson;
delete(x);
if(t) de(t);
}
int main()
{
int T;
scanf("%d",&T);
getchar();
while(T--)
{
input.clear();
gets(input.s);
build();
findst();
con.clear();
dfs(root);
st->lson=NULL;//
last->rson=NULL;//最后这个结点不处理会PE的!!
print();
de(st);
}

return 0;
}
/*
2
ABC DE G F
*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: