中序线索二叉树的插入
原题要求:试写一个算法,在中序线索二叉树的结点*p之下,插入一棵以结点*x为根、只有左子树的中序线索二叉树,使*x为根的二叉树称为*p的左子树。若*p原来有左子树,则令它为*x的右子树。完成插入之后的二叉树应保持线索化特性。
#include <iostream>
#define ERROR 0
#define OK 1
#include"stdlib.h"
#include <cstddef>
using namespace std;
typedef struct BiThrNode{
char data;
struct BiThrNode *lchild,*rchild;
int ltag,rtag;
BiThrNode(char dt) : data(dt), lchild(NULL), rchild(NULL),ltag(0),rtag(0) {}
}BiThrNode,*BiThrTree;
BiThrTree pre=NULL;
void Inthreading(BiThrTree p)
{
if(p)
{
Inthreading(p->lchild);
if(pre != NULL &&p->lchild==NULL)
{
p->ltag=1;
p->lchild=pre;
}
if(pre->rchild==NULL)
{
pre->rtag=1;
pre->rchild=p;
}
pre=p;
Inthreading(p->rchild);
}
}
BiThrTree InOrderThread(BiThrTree h, BiThrTree t)
{
if(!(h=(BiThrTree)malloc(sizeof(BiThrNode))))
{cout<<"错误"<<endl;
return false;}
h->ltag=0;h->rtag=1;
h->rchild=h;
if(!t)h->lchild=h;
else{h->lchild=t;pre=h;
Inthreading(t);
pre->rchild=h;
pre->rtag=1;
h->rchild=pre;}
return h;
}
BiThrTree last(BiThrTree t)
{
BiThrTree p;
p = t->lchild; //p指向根结点
while(p != t&&p->lchild!=t)
{
while(p->ltag == 0) //当ltag = 0时循环到中序序列的第一个结点
{
p = p->lchild;
}
while(p->rtag ==1 && p->rchild != t&&p->lchild!=t)
{
p = p->rchild;
}
if(p->lchild!=t)
{p = p->rchild; } //p进入其右子树
}
return p;
}
BiThrTree find(BiThrTree t,char dt)
{
BiThrTree p;
p = t->lchild; //p指向根结点
while(p != t&&p->data!=dt)
{
while(p->ltag == 0) //当ltag = 0时循环到中序序列的第一个结点
{
p = p->lchild;
}
while(p->rtag ==1 && p->rchild != t&&p->data!=dt)
{
p = p->rchild;
}
if(p->data!=dt)
{p = p->rchild; } //p进入其右子树
}
return p;
}
int InOrderThraverse(BiThrTree t)
{
BiThrTree p;
p = t->lchild; //p指向根结点
while(p != t)
{
while(p->ltag == 0) //当ltag = 0时循环到中序序列的第一个结点
{
p = p->lchild;
}
cout<<p->data; //显示结点数据,可以更改为其他对结点的操作
while(p->rtag ==1 && p->rchild != t)
{
p = p->rchild;
cout<<p->data;
}
p = p->rchild; //p进入其右子树
}
return OK;
}
int check(BiThrTree t)
{
if(t==NULL){cout<<"t空"<<endl;return 1;}
else cout<<"t不空,头结点:"<<t->lchild->data<<' '<<"next:"<<t->lchild->rchild->data<<endl;return 0;
}
BiThrTree insert(BiThrTree t1,BiThrTree t2,BiThrTree fn,BiThrTree last) //t2插入t1
{
if(fn->ltag==0){ //fn有左子树
fn->rtag=0;
fn->rchild=t2->lchild;
last->lchild=fn;
t2->lchild->rchild=t1->lchild;
delete(t2);
}
else if(fn->ltag==1&&fn->lchild==t1)
{
fn->ltag=0;
fn->lchild=t2->lchild;
t2->lchild->rchild=fn;
last->lchild=t1;
delete(t2);
}
else{
fn->ltag=0;
fn->lchild=t2->lchild;
t2->lchild->rchild=fn;
last->lchild=t1;
delete(t2);
}
return t1;
}
int main()
{
char dt;
BiThrTree t1,t2,init1,init2,findnode,last2;
t1=(BiThrTree)malloc(sizeof(BiThrNode));
t2=(BiThrTree)malloc(sizeof(BiThrNode));
init1=(BiThrTree)malloc(sizeof(BiThrNode));
init2=(BiThrTree)malloc(sizeof(BiThrNode));
last2=(BiThrTree)malloc(sizeof(BiThrNode));
findnode=(BiThrTree)malloc(sizeof(BiThrNode));
BiThrNode root1('a'),node1('b'), node2('c'), node3('d'), node4('e');
BiThrNode root2('f'),node5('g'),node6('h');
root1.lchild=&node1;
root1.rchild=&node2;
node1.lchild=&node3;
node2.rchild=&node4;
root2.lchild=&node5;
node5.lchild=&node6;
init1=&root1;init2=&root2;
cout<<"二叉树创建完成"<<endl; //建立二叉树
t1=InOrderThread(t1, init1); //加入头结点,并线索化
t2=InOrderThread(t2,init2);
cout<<"线索二叉树创建完成"<<endl;
//二叉树图示: 原树: a 插入树: f
// / \ /
// b c g
// / \ /
// d e h
cout<<"请输入被插入节点:"<<endl;
cin>>dt;
findnode=find(t1,dt);last2=last(t2);
t1=insert(t1,t2,findnode,last2);
cout<<"输出插入后中序线索二叉树的内容:"<<endl;
InOrderThraverse(t1);
return 0;
}