二叉树中序非递归带线索化
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
#include
#include
#define MAX 100
typedef struct node{
int data;
struct node *lchild,*rchild;
int lflag,rflag;
}bitree;
typedef struct s{
bitree *data[MAX];
int top;
}stack;
//对栈的操作
//初始化
void initial(stack *s){
s->top=-1;
}
//判空
int isempty(stack *s){
return(s->top<0);
}
//进栈
int push(stack *s,bitree *x){
if(s->top>=MAX-1){
printf("栈满溢出错误!");
return 0;
}
else{
s->top++;
s->data[s->top]=x;
return s->top;
}
}
//出栈
bitree *pop(stack *s){
if(isempty(s)){
printf("栈空,无法出栈!");
return 0;
}
else{
return s->data[s->top--];
}
}
//取顶
bitree *gettop(stack *s){
if(isempty(s)){
printf("栈空!");
return 0;
}
else
return s->data[s->top];
}
//前序递归建立二叉树
bitree *create(){
bitree *t;
int x;
printf("请输入正整数,前序添加,以0结束该层:\n");
scanf("%d",&x);
if(x==0)
t=NULL;
else{
t=(bitree*)malloc(sizeof(bitree));
t->data=x;
t->lchild=create();
t->rchild=create();
}
return t;
}
//中序遍历二叉树
void print(bitree *root){
bitree *p=root;
stack s;
int n=0;
initial(&s);
printf("非递归中序遍历,不使用线索;\n");
if(p==NULL){
printf("二叉树为空!");
return;
}
else{
do{
while(p){
//
push(&s,p);
p=p->lchild;
}
if(!isempty(&s)){
//因为pop中有了对于isempty的判断,这里不用也行
p=pop(&s);
n++;
printf("data[%d]=%d\n",n,p->data);
p=p->rchild;
}
else
return;
}while(1);
}
}
//中序线索化二叉树
void thread (bitree *root){
bitree *p=root,*pre=NULL;
stack s;
int n=0;
initial(&s);
if(p==NULL){
printf("二叉树为空!");
return;
}
else{
do{
while(p){
//
push(&s,p);
p=p->lchild;
}
if(!isempty(&s)){
//因为pop中有了对于isempty的判断,这里不用也行
p=pop(&s);
//遍历用: printf("data[%d]=%d\n",n,p->data);
//线索化代码
if(p->lchild==NULL)
p->lflag=1;
else
p->lflag=0;
if(p->rchild==NULL)
p->rflag=1;
else
p->rflag=0;
if(pre){
if(pre->rflag==1)
pre->rchild=p;
if(p->lflag==1)
p->lchild=pre;
}
pre=p;//pre一定要跟随p而走,但是这句不能放在上面的pop之前,因
//为又一个大循环的时候,走到pop那句,p已经是 空的了。放在这个地方是最好的!
p=p->rchild;
}
else
return;
}while(1);
}
}
//线索化查找中序后继
bitree *midNext(bitree *p){
bitree *q;
if(p->rflag==1)
return(p->rchild);
else{
q=p->rchild;
while(q->lflag==0)
q=q->lchild;
return q;
}
}
//使用线索化中序遍历
void printThread (bitree *root){
bitree *p=root;
int n=0
;
printf("线索化中序遍历:\n");
if(p!=NULL){
while(p->lflag==0)
p=p->lchild;
do{
n++;
printf("data[%d]=%d\n",n,p->data);
p=midNext(p);
}while(p!=NULL);
}
}
//前序实现左右子树的位置交换
void exchange(bitree *root){
bitree *p=root,*temp;
stack s;
int n=0;
initial(&s);
if(p==NULL){
printf("二叉树为空!");
return;
}
else{
do{
while(p){
n++;
temp=p->lchild;
p->lchild=p->rchild;
p->rchild=temp;
if(p->rchild){
push(&s,p->rchild);
}
p=p->lchild;
}
if(!isempty(&s)){
//因为pop中有了对于isempty的判断,这里不用也行
p=pop(&s);
}
else
return;
}while(1);
}
}
//前序实现第N个节点的查找
int findk(bitree *root,int k){
//注意,这里的k从1开始!
bitree *p=root;
stack s;
int n=0;
initial(&s);
if(p==NULL){
printf("二叉树为空!");
return 0;
}
else{
do{
while(p){
n++;
if(n==k){
return p->data;
}
if(p->rchild){
push(&s,p->rchild);
}
p=p->lchild;
}
if(!isempty(&s)){
//因为pop中有了对于isempty的判断,这里不用也行
p=pop(&s);
}
else
return 0;
}while(1);
}
}
int main(){
bitree *tree;
int k;
tree=create();
printf("当前树的内容为:\n");
print(tree);
//线索化以及输出
thread(tree);
printThread(tree);
//查找指定位置k
printf("输入要查找的位置,从1开始:\n");
scanf("%d",&k);
printf("data[%d]=%d\n",k,findk(tree,k));
//交换左右
printf("交换左右子树以后:\n");
exchange(tree);
print(tree);
return 0;
}