中序线索二叉树的遍历

1.1 说明 因为很多篇幅都和前面帖子内容重合 故本次只给出伪代码
//二叉树结构体
typedef struct ThreadNode {
	int data;
	struct ThreadNode *lchild , *rchild;
	int ltag,rtag; //1是线索
} ThreadNode, *ThreadTree;

ThreadNode *pre=NULL; //定义一个全局变量作为pre前序

/**
    二叉树的创建、线索化、省略
*/
1.2 中序线索树的遍历
//线索树的遍历

/**
	中序线索遍历
	中序遍历: 左 根 右
	(1)前驱
		对于一个结点p来说,它有两种情况
		1.1) p->ltag == 1
			则p的左孩子为p的前驱
		1.2) p->ltag == 0
			左线索化== 0 则p一定有左孩子
			因为是左根右的遍历 所以p的前驱一定是它的左子树最右下角的那个结点 
	(2)后继
		对于一个结点p来说,它有两种情况
		2.1) p->rtag == 1
			则p的右孩子为p的后继
		2.2) p->rtag == 0
			则是右子树中第一个左子树的最左下角结点 	 
*/

//(1)找前驱

//获取当前树最后一个结点 
ThreadNode *lastNode(ThreadNode *p){
	while(p->rtag == 0){
		//循环找到左子树最右下的结点 即最后一个结点 
		p = p->rchild;
	}
	return p;
}

ThreadNode *preNode(ThreadNode *p){
	if(p->ltag == 1) return p->lchild;
	else return lastNode(p->lchild); //返回左子树的最后一个结点 
	
//		下面内容应该耦合为一个函数,这样可以方便在总体遍历的时候找到开始节点 
//	else{
//		ThreadNode *q = p->lchild;
//		//0.2) 左子树最右下角的元素
//		while(q->rtag == 0){ //得是未被线索化的右孩子 而且最右下角的孩子右节点一定会被线索化 
//			//循环找到左子树最右下的结点 即最后一个结点 
//			q = q->rchild;
//		}
//		return q;
//	}

}

//(2)找后继

//获取当前树的第一个结点 
ThreadNode *firstNode(ThreadNode *p){
	while(p->ltag == 0){
		p = p->lchild;
	}
	return p;
}

ThreadNode *nextNode(ThreadNode *p){
	if(p->rtag == 1) return p->rchild;
	//否则返回右子树的第一个结点 
	else return firstNode(p->rchild);
} 
1.3 main函数及运行测试
int main() {
	ThreadTree root = createNode(1); //root

	//第二层
	root->lchild = createNode(2);
	root->rchild = createNode(3);

	//第三层
	root->lchild->lchild = createNode(4);
	root->lchild->rchild = createNode(5);
	root->rchild->lchild = createNode(6);

	//第四层
	root->lchild->rchild->lchild = createNode(7);
	
	//中序线索化(详细代码见前贴)
	createInThreadTree(root);
	
	//中序正向线索遍历 
	printf("\n开始正向遍历:\n");
	for(ThreadNode *i = firstNode(root) ; i != NULL ; i = nextNode(i) ){
		printf("i: %d\n",i->data);
	}
	
	//中序逆向线索遍历
	printf("\n开始逆向遍历:\n");
	for(ThreadNode *i = lastNode(root) ; i != NULL ; i = preNode(i)){
		printf("i: %d\n",i->data);	
	} 

	/*
	           1
	        /     \
	       2       3
	      / \     /
	     4   5   6
	       	/
	       7
	*/

	return 0;
}

可以看到遍历成功

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值