线索二叉树的基本操作

2023-06-26 0 1,160

线索二叉树的结构体

//线索二叉树定义
typedef struct ThreadTreeNode{
    int data;
    int ltag,rtag;
    struct ThreadTreeNode *lchild,*rchild,*parent;
}ThreadTreeNode,*ThreadTree;

线索二叉树的基本操作

//带父结点的二叉树的建立
ThreadTree createWP(){
	int data;
	scanf("%d",&data);
	ThreadTree t = NULL;
	if(data!=-1){
		t = (ThreadTreeNode*)malloc(sizeof(ThreadTreeNode));
		t->ltag = t->rtag = 0;
		t->data = data;
		t->lchild = createWP();
		//父节点绑定 
		if(t->lchild){
			t->lchild->parent = t;
		} 
		t->rchild = createWP();
		//父节点绑定 
		if(t->rchild){
			t->rchild->parent = t;
		}
	}else{
		return t;
	}
} 

////对二叉树中序线索化
//递归子函数 
void InThreadBiTree(ThreadTree &t,ThreadTree &p){
	if(t){
		InThreadBiTree(t->lchild,p);
		if(t->lchild==NULL){
			t->lchild = p;
			t->ltag = 1;
		} 
		if(t->rchild==NULL){
			t->rchild = p;
			t->rtag = 1;
		}
		p = t;
		InThreadBiTree(t->rchild,p);
	}
}
//主函数
void CreateInThread(ThreadTree t){
	ThreadTree p = NULL;
	if(t){
		InThreadBiTree(t,p);
		p->rchild = NULL;
		p->rtag = 1;
	} 
} 

////中序线索二叉树的遍历
//求中序线索二叉树序列中的第一个结点
ThreadTree FirstNode(ThreadTree t){
	//寻找最左下的结点 
	while(t->ltag == 0){
		//有左孩子就向左移动 
		t = t->lchild;
	}
	return t;
} 

//求中序线索二叉树中某个结点的后继
ThreadTree NextNode(ThreadTree t){
	if(t->rtag != 1){
		return FirstNode(t->rchild); //没有直接后继,就找右子树中最靠左的结点 
	};
	return t->rchild;
} 

//遍历中序线索二叉树
void printInThreadTree(ThreadTree t){
	for(ThreadTree p=FirstNode(t);p!=NULL;p=NextNode(t)){
		printf("%d",p->data);
	}
} 
////对二叉树的前序线索化
//递归子函数
void PreThreadBiTree(ThreadTree &t,ThreadTree &p){
	if(t){
		if(t->lchild==NULL){
			t->lchild = p;
			t->ltag = 1;
		}
		if(t->rchild==NULL){
			t->rchild = p;
			t->rtag = 1;
		}
		p = t;
		//一定得有判断条件,防止转圈
		//(例如去掉条件,t->ltag是1时没有判断条件,前驱结点与本结点构成一个环,不停循环) 
		if(t->ltag == 0)PreThreadBiTree(t->lchild,p);
		if(t->rtag == 0)PreThreadBiTree(t->rchild,p);
	}
}
//主函数
void PreThread(ThreadTree t){
	ThreadTree p = NULL;
	if(t){
		PreThreadBiTree(t,p);
		p->rchild = NULL;
		p->rtag = 1;
	}
} 
////前序结果二叉树的遍历
//求前序结点二叉树的某个结点的前驱
ThreadTree PrePNode(ThreadTree t){
	if(t->ltag==1){	
		return t->lchild;
	}else{
		//分三种情况,需要用到父结点
		//如果t是父结点的左结点,根据NLR,其前驱为其父节点 
		if(t->parent->lchild==t){
			return t->parent;
		//如果t是父节点的右结点,且父节点无左子结点,则前驱依然是父结点 
		}else if(t->parent->ltag == 1){
			return t->parent;
		//前面两个条件都失效,证明该结点为右结点且父结点有左孩子,前驱应该是左孩子的最右下结点 
		//并且该节点一定是一个叶子节点,所以左右线索都应为1 
		}else{
			ThreadTree p = t->parent->lchild;
			//遍历(难点)
			while(p->rtag != 1 || p->ltag != 1){
	   		//向右不停查找,直到节点无右子树 
	   		    while(p->rtag == 0)p = p->rchild;
	   		    //找到无右子树的节点,检查是否有左子树 
	   		    if(p->ltag == 0)
	   		    //若有左子树,向左走一步,继续向右走,直到找到最右下节点 
	   		    p = p->lchild;
		    } 
			return p;
		}
		
	}
} 
//求前序结点二叉树的某个结点的后继
ThreadTree PostPNode(ThreadTree t){
	if(t->rtag==1){
		//有后继线索,直接返回 
		return t->rchild; 
	}else{
		//该节点有右孩子,分两种情况讨论 
		//该节点有左孩子,返回左孩子 
		if(t->rtag==0)return t->lchild;
		//否则该节点无左孩子,返回右孩子为其后继 
		else return t->rchild; 
	}
}
//遍历前序结点二叉树 
void PrintPTTree(ThreadTree t){
	for(ThreadTree p = t;p!=NULL;p = PostPNode(p)){
		printf("%d",p->data);
	}
}

////对二叉树的后序线索化
//递归子函数
ThreadTree PostThreadBiTree(ThreadTree &t,ThreadTree &p){
	 if(t){
	 	if(t->ltag==0)
	 	PostThreadBiTree(t->lchild,p);
	 	if(t->rtag==0)
		PostThreadBiTree(t->rchild,p);
		p = t;
		if(t->lchild==NULL){
			t->lchild = p;
			t->ltag = 1;
		} 
		if(t->rchild == NULL){
			t->rchild = p;
			t->rtag = 1;
		}
	 }
}
//主函数
void PostThread(ThreadTree t){
	ThreadTree p = NULL;
	if(t){
		PostThreadBiTree(t,p);
		p->rchild = NULL;
		p->rtag = 1;
	}
} 
////前序结果二叉树的遍历
//求前序结点二叉树的某个结点的前驱
ThreadTree PrePostNode(ThreadTree t){
	if(t->ltag == 1){
		//有直接后继 
		return t->lchild;
	}else{
		//有左孩子,先看有没有右孩子 
		if(t->rtag==0)return t->rchild;
		else return t->lchild;
	}
}

//求前序结点二叉树的某个结点的后继
ThreadTree PostPostNode(ThreadTree t){
	if(t->rtag == 1){
		//有直接后继 
		return t->rchild;
	}else{
		//父节点的右孩子是否为本节点,是的话直接返回父节点 
		if(t->parent->rchild == t){
			return t->parent;
		//父节点无右孩子,本节点是左孩子,是的话也直接返回父节点
		}else if(t->parent->rtag == 1){
			return t->parent;
		}else{
		//后继节点应为父节点右孩子的最左下节点,且应为叶节点 
			ThreadTree p = t->parent->rchild;
			while(p->ltag == 0 && p->rtag == 0){
				while(p->ltag == 0){
					p = p->lchild;
				}
				//是否还有右子节点,有的话则不为叶子节点,向右走一下 
				if(p->rtag == 0){
					p = p->rchild;
				}
			} 
			return p;
		}
	}
} 

//后序线索二叉树的打印
void printPost(ThreadTree t){
	int stack[MAXSIZE],top=-1;
	//由于后续二叉树的特性LRN,打印出来应该是后序节点排列的倒序
	//利用栈后进先出的特点,我们选用一个栈来存储数据 
	for(ThreadTree p = t;t!=NULL;t=PrePostNode(t)){
		stack[++top] = p->data;
	}
	while(top>=0){
		printf("%d",stack[top--]); 
	}
}
收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

本站部分资源收集自互联网,我站仅分享内容,仅供用户个人研究,不提供商业使用,如有侵权下架处理,觉得资源内容不错请您在官方渠道购买正版,您在阅读的同时下载的内容本站不承担任何法律责任!Some resources of this website are collected from the Internet. We only share the content, which is only for personal research of users, and not for commercial use. If there is infringement and off shelf processing, please purchase the authentic version of the resource content from the official channel if you think it is good. We will not bear any legal responsibility for the content you download while reading!

橙凰素材-精品源码下载|正版主题更新 学习交流 线索二叉树的基本操作 https://b.bqzmz.com/2023/06/26/%e7%ba%bf%e7%b4%a2%e4%ba%8c%e5%8f%89%e6%a0%91%e7%9a%84%e5%9f%ba%e6%9c%ac%e6%93%8d%e4%bd%9c/

为用户提供极致的体验

常见问题
  • 正版主题是指站长在指定渠道购买的官方主题,提供作者联系,资源支持,长期更新等等内容
查看详情
  • 非常抱歉,请联系网站页脚的客服,我们将在核实后下架处理并返还给您此资源的收益(会扣去网站运营的费用),谢谢理解!
查看详情
  • 网络资源是站长从互联网分享收集而来的内容,本站不会做测试,直接分享,不包源码可用性,运营性,如有需求点击右边的联系正版,谢谢!
查看详情
  • 如果资源不是最新版本,请在资源下方评论区进行催更或提交工单处理,我们会尽快更新并通过邮箱通知您。
查看详情

相关文章

发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务