目录
二叉树的创建
递归创建
先序创建
void CreateTree(Betree *r)
{
char ch;
ch=getchar();
if(ch=='#')
*r=NULL;
else
{
(*r)=new Nodetree;
(*r)->ch=ch;
CreateTree(&((*r)->Lchild));
CreateTree(&((*r)->Rchild));
}
}
前序中序创建
void CreateTree(Betree *r,char Last[],char In[],int LastL,int LastR,int il,int ir)//中序数组+后序数组递归创建二叉链表
{
if(il>ir)
*r=NULL;
else
{
*r=new Nodetree;
(*r)->ch=Last[LastR];
int mid=il;
while(In[mid]!=Last[LastR])
{
mid++;
}
CreateTree(&((*r)->Lchild),Last,In,LastL,LastL+mid-il-1,il,mid-1);
CreateTree(&((*r)->Rchild),Last,In,LastL+mid-il,LastR-1,mid+1,ir);
}
}
create(preL+1,preL+mid-inL,inL,mid-1);
create(preL+mid-inL+1,preR,mid+1,inR);
中序后序创建
void CreateTree(Betree *r,char Last[],char In[],int LastL,int LastR,int il,int ir)//中序数组+后序数组递归创建二叉链表
{
if(il>ir)
*r=NULL;
else
{
*r=new Nodetree;
(*r)->ch=Last[LastR];
int mid=il;
while(In[mid]!=Last[LastR])
{
mid++;
}
CreateTree(&((*r)->Lchild),Last,In,LastL,LastL+mid-il-1,il,mid-1);
CreateTree(&((*r)->Rchild),Last,In,LastL+mid-il,LastR-1,mid+1,ir);
}
}
完整代码
#include<bits/stdc++.h>
using namespace std;
typedef struct tree
{
char ch;
struct tree *Lchild;
struct tree *Rchild;
}Nodetree,*Betree;
void CreateTree(Betree *r,char Last[],char In[],int LastL,int LastR,int il,int ir)//中序数组+后序数组递归创建二叉链表
{
if(il>ir)
*r=NULL;
else
{
*r=new Nodetree;
(*r)->ch=Last[LastR];
int mid=il;
while(In[mid]!=Last[LastR])
{
mid++;
}
CreateTree(&((*r)->Lchild),Last,In,LastL,LastL+mid-il-1,il,mid-1);
CreateTree(&((*r)->Rchild),Last,In,LastL+mid-il,LastR-1,mid+1,ir);
}
}
void print(Betree r)
{
if(r==NULL)
return;
else
{
cout<<r->ch;
print(r->Lchild);
print(r->Rchild);
}
}
int main()
{
char Last[10010],In[10010];
cin>>In>>Last;
// int Lastl=;
// int ilength=;
Betree r;
r=new Nodetree;
CreateTree(&r,Last,In,0,strlen(Last)-1,0,strlen(In)-1);
print(r);
}
#include<bits/stdc++.h>
#define MAX 100
using namespace std;
typedef struct tree
{
char ch;
struct tree *Lchild;
struct tree *Rchild;
}Nodetree,*Betree;
typedef struct stack1
{
Betree a[MAX];
int top;
}Stack1;
typedef struct stack2
{
Betree a;
bool t;
}Stack2;
void push(Stack1 &s,Betree b)
{
s.a[++s.top]=b;
}
Betree pop(Stack1 &s)
{
s.top--;
return s.a[s.top+1];
}
void CreateTree(Betree *r)
{
char ch;
ch=getchar();
if(ch=='#')
*r=NULL;
else
{
(*r)=new Nodetree;
(*r)->ch=ch;
CreateTree(&((*r)->Lchild));
CreateTree(&((*r)->Rchild));
}
}
void Nopre(Betree r)
{
Stack1 s1;
s1.top=-1;
while(r!=NULL)
{
cout<<r->ch<<" ";
push(s1,r);
if(r->Lchild!=NULL)
{
r=r->Lchild;
}
else if(s1.top!=-1)
{
while(s1.top!=-1)
{
r=pop(s1);//出栈
r=r->Rchild;
if(r!=NULL)break;//如果当前结点不是叶子结点,就退出,对当前结点的右结点进行循环。
}
}
else
r=NULL;
}
}
void NoIn(Betree r)//非递归中序遍历
{
Stack1 s1;
s1.top=-1;
while(r!=NULL)
{
push(s1,r);//进栈
if(r->Lchild!=NULL)
{
r=r->Lchild;
}
else if(s1.top!=-1)
{
while(s1.top!=-1)
{
r=pop(s1);//出栈
cout<<r->ch<<" ";
r=r->Rchild;
if(r!=NULL)break;//如果当前结点不是叶子结点,就退出,对当前结点的右结点进行循环。
}
}
else
r=NULL;
}
}
void NoLast(Betree r)//非递归后序遍历
{
Stack2 s2[100];
int top=-1;
do
{
while(r!=NULL)//有左子结点就一直往左
{
s2[++top].a=r;
r=r->Lchild;
s2[top].t=false;//每个都赋false说明每个都往左
}
while(top!=-1&&s2[top].t==true)//如果左右都判断完了,说明那个节点两边都是true,这条语句就要往上(跟结点方向)循环多次
{
r=s2[top--].a;//出栈
cout<<r->ch<<" ";
}
if(top!=-1)
{
s2[top].t=true;
r=s2[top].a->Rchild;//左边完,换右边
}
}while(top!=-1);
}
void pre(Betree a)
{
if(a==NULL)
return;
else
{
cout<<a->ch<<" ";
pre(a->Lchild);
pre(a->Rchild);
}
}
void in(Betree a)
{
if(a==NULL)
return;
else
{
in(a->Lchild);
cout<<a->ch<<" ";
in(a->Rchild);
}
}
void last(Betree a)
{
if(a==NULL)
return;
else
{
last(a->Lchild);
last(a->Rchild);
cout<<a->ch<<" ";
}
}
int main()
{
Betree r=NULL;
r=new Nodetree;
CreateTree(&r);
pre(r);
cout<<endl;
in(r);
cout<<endl;
last(r);
cout<<endl;
Nopre(r);
cout<<endl;
NoIn(r);
cout<<endl;
NoLast(r);}
一些练习
二叉树的遍历
前序遍历-非递归
void Nopre(Betree r)
{
Stack1 s1;
s1.top=-1;
while(r!=NULL)
{
cout<<r->ch<<" ";
push(s1,r);
if(r->Lchild!=NULL)
{
r=r->Lchild;
}
else if(s1.top!=-1)//栈不为空
{
while(s1.top!=-1)
{
r=pop(s1);//出栈
r=r->Rchild;
if(r!=NULL)break;//如果当前结点不是叶子结点,就退出,对当前结点的右结点进行循环。
}
}
else
r=NULL;
}
}
中序遍历-非递归
void NoIn(Betree r)//非递归中序遍历
{
Stack1 s1;
s1.top=-1;
while(r!=NULL)
{
push(s1,r);//进栈
if(r->Lchild!=NULL)
{
r=r->Lchild;
}
else if(s1.top!=-1)
{
while(s1.top!=-1)
{
r=pop(s1);//出栈
cout<<r->ch<<" ";
r=r->Rchild;
if(r!=NULL)break;//如果当前结点不是叶子结点,就退出,对当前结点的右结点进行循环。
}
}
else
r=NULL;
}
}
后序遍历-非递归
void NoLast(Betree r)//非递归后序遍历
{
Stack2 s2[100];
int top=-1;
do
{
while(r!=NULL)//有左子结点就一直往左
{
s2[++top].a=r;
r=r->Lchild;
s2[top].t=false;//每个都赋false说明每个都往左
}
while(top!=-1&&s2[top].t==true)//如果左右都判断完了,说明那个节点两边都是true,这条语句就要往上(跟结点方向)循环多次
{
r=s2[top--].a;//出栈
cout<<r->ch<<" ";
}
if(top!=-1)
{
s2[top].t=true;
r=s2[top].a->Rchild;//左边完,换右边
}
}while(top!=-1);
}
层序遍历
void FloorPrint_QUEUE(pTreeNode &Tree) //层序遍历_队列实现
{
queue < pTreeNode> q;
if (Tree != NULL)
{
q.push(Tree); //根节点进队列
}
while (q.empty() == false) //队列不为空判断
{
cout << q.front()->data << " → ";
if (q.front()->leftPtr != NULL) //如果有左孩子,leftChild入队列
{
q.push(q.front()->leftPtr);
}
if (q.front()->rightPtr != NULL) //如果有右孩子,rightChild入队列
{
q.push(q.front()->rightPtr);
}
q.pop(); //已经遍历过的节点出队列
}
}
法二
void FloorPrint(pTreeNode Tree) //层序遍历
{
pTreeNode temp[100]; //创建pTreeNode指针类型的指针数组
int in = 0;
int out = 0;
temp[in++] = Tree; //先保存二叉树根节点
while (in > out)
{
if (temp[out])
{
cout << temp[out]->data << " → ";
temp[in++] = temp[out]->leftPtr;
temp[in++] = temp[out]->rightPtr;
}
out++;
}
}
二叉树的应用
哈夫曼
一些练习
最小生成树的权值之和 | |
【问题描述】 1-3:6 【样例说明】 | 10 |
#include <bits/stdc++.h>
using namespace std;
#define max 0x7fffffff;
struct graph
{
int arc[200][200];
int vexnum, arcnum;
};
struct a
{
int adj;
int lowcost;
} edge[200];
void create(graph *g)
{
cin >> g->vexnum >> g->arcnum;
for (int i = 1; i <= g->vexnum; i++)
for (int j = 1; j <= g->vexnum; j++)
g->arc[i][j] = max;
int weight, i, j;
for (int k = 0; k < g->arcnum; k++)
{
cin >> i >> j >> weight;
g->arc[i][j] = weight;
g->arc[j][i] = weight;
}
}
int findmin(graph g)
{
int index = -1;
int min = max;
for (int i = 1; i <= g.vexnum; i++)
{
if (min > edge[i].lowcost && edge[i].lowcost != 0)
{
min = edge[i].lowcost;
index = i;
}
}
return index;
}
void prime(graph g, int vex)
{
int sum = 0;
int k;
for (int j = 1; j <= g.vexnum; j++)
{
edge[j].adj = vex;
edge[j].lowcost = g.arc[vex][j];
}
edge[vex].lowcost = 0;
for (int i = 1; i < g.vexnum; i++)
{
k = findmin(g);
sum += edge[k].lowcost;
cout << edge[k].adj << "-" << k << ":" << edge[k].lowcost << endl;
edge[k].lowcost = 0;
for (int i = 1; i <= g.vexnum; i++)
{
if (g.arc[k][i] < edge[i].lowcost)
{
edge[i].adj = k;
edge[i].lowcost = g.arc[k][i];
}
}
}
cout << sum;
}
int main()
{
graph g;
create(&g);
prime(g, 1);
}
二叉树根据中序和后序求前序遍历
【问题描述】 根据一棵二叉树的中序遍历序列和后序遍历序列,求这棵树的前序遍历序列。
【输入形式】 一棵树的中序遍历序列和该树后序遍历序列。输入序列中仅含有小写字母,且没有重复的字母
【输出形式】 一棵树的前序遍历序列
【样例输入】
dbeafcg
debfgca
【样例输出】
abdecfg
#include<bits/stdc++.h>
using namespace std;
typedef struct tree
{
char ch;
struct tree *Lchild;
struct tree *Rchild;
}Nodetree,*Betree;
void CreateTree(Betree *r,char Last[],char In[],int LastL,int LastR,int il,int ir)//中序数组+后序数组递归创建二叉链表
{
if(il>ir)
*r=NULL;
else
{
*r=new Nodetree;
(*r)->ch=Last[LastR];
int mid=il;
while(In[mid]!=Last[LastR])//定位mid
{
mid++;
}
CreateTree(&((*r)->Lchild),Last,In,LastL,LastL+mid-il-1,il,mid-1);
CreateTree(&((*r)->Rchild),Last,In,LastL+mid-il,LastR-1,mid+1,ir);
}
}
void print(Betree r)
{
if(r==NULL)
return;
else
{
cout<<r->ch;
print(r->Lchild);
print(r->Rchild);
}
}
int main()
{
char Last[10010],In[10010];
cin>>In>>Last;
Betree r;
r=new Nodetree;
CreateTree(&r,Last,In,0,strlen(Last)-1,0,strlen(In)-1);
print(r);
}
二叉树结点的共同祖先问题【问题描述】假设二叉树采用二叉链表方式存储,root指向根结点,p所指结点和q所指结点为二叉树中的两个不同结点,且互不成为根到该结点的路径上的点,编程求解距离它们最近的共同祖先。 【输入形式】二叉树的前序和中序遍历序列,用以创建该二叉树的链式存储结构;以及二叉树的两个结点数据 x 和 y 【输出形式】结点数据值为 x 和结点数据值为 y 的最近的共同祖先,若没有共同祖先则输出NULL,请注意一个结点本身不能成为另一个结点的共同祖先。 【样例输入】 GABDCEF BDAEFCG DF 【样例输出】 A |
自底向上查找,有点难度! | LeetCode:236. 二叉树的最近公共祖先_哔哩哔哩_bilibili
#include<bits/stdc++.h>
using namespace std;
struct node
{
char data;
node *l;
node *r;
};
char mid[1005], pre[1005];
node *build(int x, int y, int q, int p) // xy为前序序列的左右边界,qp为前序序列的左右边界
{
int i;
if (x > y || q > p)
return NULL;
node *root = new node;
root->data = pre[x];
root->l = NULL;
root->r = NULL;
for (i = q; i <= p; i++)
if (pre[x] == mid[i])
break;
root->l = build(x + 1, x + i - q, q, i - 1);
root->r = build(x + i - q + 1, y, i + 1, p);
return root;
}
node *dfs(node *root, node *p, node *q)
{
if (!root)
return NULL;
if (root->data == p->data || root->data == q->data)
return root;
node *l;
l= dfs(root->l, p, q);
node *r;
r= dfs(root->r, p, q);
if (l!=NULL && r!=NULL)
return root;
if (l)
return l;
if (r)
return r;
return NULL;
}
int main()
{
cin >> pre >> mid;
int len = strlen(mid);
node *root;
root = build(0, len - 1, 0, len - 1);
char a, b;
cin >> a >> b;
node *t1 = new node;
node *t2 = new node;
node *ss = new node;
t1->data = a;
t2->data = b;
ss = dfs(root, t1, t2);
if (ss != NULL && ss->data != root->data)
{
cout << ss->data;
}
else
cout << "NULL";
return 0;
}
数组存储的完全二叉树的先序遍历【问题描述】课后作业习题25:n个结点的完全二叉树顺序存储在一维数组a中,设计一个算法,实现对此二叉树的先序遍历。 【输入形式】一维数组a,以#结束输入,请接收后存储在一维数组a中 【输出形式】先序遍历序列 【样例输入】ABCDEF# 【样例输出】ABDECF |
#include <bits/stdc++.h>
using namespace std;
struct node
{
char data;
node *l, *r;
};
char a[101];
node *create(int s, int n)
{
if (s <= n)
{
node *root = new node;
root->data = a[s - 1];
root->l = create(2 * s, n);
root->r = create(2 * s + 1, n);
return root;
}
else
return NULL;
}
void qianxu(node *root)
{
if (root)
{
cout << root->data;
qianxu(root->l);
qianxu(root->r);
}
}
int main()
{
int i = 0;
while (1)
{
cin >> a[i];
if (a[i] == '#')
break;
i++;
}
node *root = create(1, i);
qianxu(root);
}
【问题描述】 考研真题:给定一颗二叉树,要求从下至上按层遍历二叉树,每层的访问顺序是从左到右,每一层单独输出一行。 【输入形式】 广义表表示的二叉树,结点元素类型为整型,且都大于0,例如:1( 2( 3 ( 4, 5 ) ), 6( 7, 8( 9, 10 ) ) ) 【输出形式】 从下至上,打印每一层的结点元素值,元素间以空格隔开。每层的访问顺序是从左到右,每一层单独输出一行。 【样例输入】 1(2(3(4,5)),6(7,8(9,10))),字符串内没有空格 【样例输出】 4 5 9 10 3 7 8 2 6 1 【评分标准】 本题目主要考察两个知识点: 1.创建二叉树存储结构 2.按层次遍历二叉树的算法 |
二叉树的深度及结点最远距离【问题描述】考研真题:求二叉树的深度及二叉树中最远两个结点的距离。 【输入形式】拓展的前序遍历序列 【输出形式】深度和距离 【样例输入】AB#C##DE#G#H##F## 【样例输出】5 6 |
#include <bits/stdc++.h>
using namespace std;
struct node
{
char data;
node *lc, *rc;
};
node *cre(char a[], int len, int &i)
{
if (i < len && a[i] != '#')
{
node *r = new node;
r->data = a[i];
r->lc = cre(a, len, ++i);
r->rc = cre(a, len, ++i);
return r;
}
else
return NULL;
}
void getdeep(node *a, int step, int &deep)
{
if (a)
{
deep = max(deep, step);
getdeep(a->lc, step + 1, deep);
getdeep(a->rc, step + 1, deep);
}
}
void getdis(node *t, int &dis)
{
int deep = 0, step = 1;
if (t == NULL)
return;
getdeep(t->lc, step, deep);
int lh = deep;
deep = 0;
getdeep(t->rc, step, deep);
int rh = deep;
if (rh + lh > dis)
dis = rh + lh;
if (t->lc)
getdis(t->lc, dis);
if (t->rc)
getdis(t->rc, dis);
}
int main()
{
char a[100];
cin >> a;
int i = 0;
node *t = cre(a, strlen(a), i);
int deep = 0, step = 1, dis = 1;
getdeep(t, step, deep);
getdis(t, dis);
cout << deep << " " << dis;
}
二叉树的创建及求解二叉树的宽度
【问题描述】求解二叉树的宽度,请用递归和非递归两种方法求解。
【输入形式】前序和中序序列建树
【输出形式】递归和非递归求解的宽度值
【样例输入】
abcdefg
cbdaegf
【样例输出】
3 3
#include <iostream>
using namespace std;
#include <cstring>
#include <queue>
struct node
{
char data;
node *lchild;
node *rchild;
};
int height = 0;
int width[1000];
char mid[1001], pre[1001];
node *build(int x, int y, int q, int p) // xy为前序序列的左右边界,qp为前序序列的左右边界
{
int i;
if (x > y || q > p)
return NULL;
node *root = new node;
root->data = pre[x];
root->lchild = NULL;
root->rchild = NULL;
for (i = q; i <= p; i++)
if (pre[x] == mid[i])
break;
root->lchild = build(x + 1, x + i - q, q, i - 1);
root->rchild = build(x + i - q + 1, y, i + 1, p);
return root;
}
void get_height(node *root, int step = 1)
{
if (root == NULL)
return;
height = max(step, height);
get_height(root->lchild, step + 1);
get_height(root->rchild, step + 1);
}
void store_wild(node *root, int i) //递归方法
{
if (root != NULL)
{
width[i]++;
// cout << i << " " << width[i] << endl;
store_wild(root->lchild, i + 1);
store_wild(root->rchild, i + 1);
}
}
int get_width1(node *root)
{
get_height(root, 1);
for (int i = 0; i < height; i++)
width[i] = 0;
store_wild(root, 0);
// for (int i = 0; i < height; i++)
// cout << width[i];
int maxx = 0;
for (int i = 0; i < height; i++)
maxx = max(maxx, width[i]);
return maxx;
}
int get_width2(node *root)
{
queue<node *> q;
node *p = root;
q.push(p);
int maxx = 0;
while (!q.empty())
{
int flag = 0;
int len = q.size();
while (flag < len)
{
flag++;
p = q.front();
q.pop();
if (p->lchild)
q.push(p->lchild);
if (p->rchild)
q.push(p->rchild);
}
maxx = max(maxx, len);
}
return maxx;
}
int main()
{
cin >> pre >> mid;
int len = strlen(mid);
node *root;
root = build(0, len - 1, 0, len - 1);
cout << get_width1(root) << " " << get_width2(root);
return 0;
}
哈夫曼编码【问题描述】读入n个字符所对应的权值,自底向上构造一棵哈夫曼树,自顶向下生成每一个字符对应的哈夫曼编码,并依次输出。另,求解某字符串的哈夫曼编码,求解某01序列的译码。 【输入形式】输入的第一行包含一个正整数n,表示共有n个字符需要编码。其中n不超过100。第二行中有n个用空格隔开的正整数,分别表示n个字符的权值,依次按照abcd...的默认顺序给出。然后是某字符串和某01序列。 【输出形式】前n行,每行一个字符串,表示对应字符的哈夫曼编码。然后是某字符串的哈夫曼编码,某01序列的译码。 【注意】保证每次左子树比右子树的权值小;如出现相同权值的,则先出现的在左子树,即下标小的在左子树。 【样例输入】 8 aabchg 00011110111111001 【样例输出】 0001 000100011011100010000 acdef |
0023算法笔记——【贪心算法】哈夫曼编码问题_风仲达的博客-优快云博客
带权路径长度【问题描述】 输入一串正整数,正整数之间用空格键分开,请建立一棵哈夫曼树,以输入的数字作为叶子节点,求这棵哈夫曼树的带权路径长度。 【输入形式】 首先输入正整数的个数n,然后是对应的n个正整数,正整数个数不超过10个 【输出形式】 输出创建的哈夫曼树的带权路径总长度 【样例输入】 5 4 5 6 7 8 【样例输出】 69 | 10.00 |
#include<stdio.h>
#include<stdlib.h>
typedef struct
{
unsigned int weight;
unsigned int parent,lchild,rchild;
}HTNode,*HuffmanTree;
void Select(HuffmanTree HT,int n,int &s1,int &s2)
{
for(int i=1;i<=n;i++)
{
if(HT[i].parent==0)
{ s1=i;
break;
}
}
for(int i=1;i<=n;i++)
{
if(HT[i].parent==0&&HT[i].weight<=HT[s1].weight)
s1=i;
}
for(int i=1;i<=n;i++)
{
if(HT[i].parent==0&&i!=s1)
{ s2=i;
break;
}
}
for(int i=1;i<=n;i++)
{
if(HT[i].parent==0&&HT[i].weight<=HT[s2].weight&&i!=s1)
s2=i;
}
}
void HuffmanCoding(HuffmanTree &HT,int *w,int n)
{
if(n<=1) return;
int m=2*n-1;
HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode));
HuffmanTree p=HT+1;
int i,s1,s2;
for(i=1;i<=n;i++,p++ ,w++) //前n个节点放n个叶子
{
p->weight=*w;
p->parent=0;
p->rchild=0;
p->lchild=0;
}
for(;i<=m;i++,p++) //后面n-1放有孩子的节点
{
p->weight=0;
p->parent=0;
p->rchild=0;
p->lchild=0;
}
for(i=n+1;i<=m;i++) //建立哈夫曼树
{
Select(HT,i-1,s1,s2);
//printf("%d %d\n",s1,s2);
HT[s1].parent=i;
HT[s2].parent=i;
HT[i].lchild=s1;
HT[i].rchild=s2;
HT[i].weight=HT[s1].weight+HT[s2].weight;
}
}
int WeightLength(HuffmanTree HT,int n) //n个叶子
{
int c,s=0;//c是路径长度,s是带权路径长度
for(int i=1;i<=n;i++)
{
c=0;
int k=i;
while(HT[k].parent!=0)
{
k=HT[k].parent;
c++;
}
s=s+c*HT[i].weight;
}
return s;
}
int main()
{
int n;
HuffmanTree HT;
scanf("%d",&n);
int w[100];
for(int i=0;i<n;i++)
scanf("%d",&w[i]);
HuffmanCoding(HT,w,n);
printf("%d",WeightLength(HT,n));
return 0;
}
中序线索二叉树
【问题描述】创建一棵二叉树,接着中序线索化该二叉树,然后编写相应函数遍历该中序线索二叉树
【编码要求】线索二叉树遍历过程中不能使用递归、不能使用栈。
【输入形式】二叉树拓展的前序遍历序列
【输出形式】中序遍历序列
【样例输入】AB#D##CE###
【样例输出】BDAEC
#include <iostream>
using namespace std;
#include <cstring>
struct node
{
char data;
node *lchild;
node *rchild;
int ltag, rtag;
};
char a[100];
node *build(int len, int &i)
{
if (i < len && a[i] != '#')
{
node *r = new node;
r->data = a[i];
r->ltag = r->rtag = 0;
r->lchild = build(len, ++i);
r->rchild = build(len, ++i);
return r;
}
else
return NULL;
}
node *pre = NULL;
void build_thread(node *root)
{
if (root == NULL)
return;
build_thread(root->lchild);
if (root->lchild == NULL)
{
root->lchild = pre;
root->ltag = 1;
}
if (pre != NULL && pre->rchild == NULL)
{
pre->rchild = root;
pre->rtag = 1;
}
pre = root;
build_thread(root->rchild);
}
node *left(node *p)
{
while (p != NULL && p->ltag == 0 && p->lchild != NULL)
p = p->lchild;
return p;
}
void output(node *root)
{
node *p = left(root);
while (p != NULL)
{
cout << p->data;
if (p->rtag == 1)
{
p = p->rchild;
}
else
{
p = left(p->rchild);
}
}
return;
}
int main()
{
ios::sync_with_stdio(false);
cin >> a;
int i = 0;
node *r = build(strlen(a), i);
build_thread(r);
output(r);
}