从零开始学数据结构系列之第三章《后续线索二叉树总代码部分》

文章目录


回顾查找首节点

这是我们中序线索二叉树写的

c 复制代码
/* 找到最左的节点数 */
TreeNode* getFirst(TreeNode* T) 
{
	while (T -> ltag == 0)
        T = T -> lchild;
    return T;

}

仔细想想,我们中序遍历这个是 左 右 中,而我们这个先序遍历是直接寻找最左边的节点,所以我们以防万一下图这种情况

如果是这种情况,我们想上述的代码是不能有效的完成工作的,所以我们需要一些简单的修改

c 复制代码
/* 找到最左的节点数 */
TreeNode* getFirst(TreeNode* T) 
{
	while (T -> ltag == 0)
        T = T -> lchild;
    if(T -> rtag == 0)
        getFirst(T -> rchild);
    return T;
}

查找下一个节点

c 复制代码
TreeNode* getNext(TreeNode* node) 
{
	if (node -> rtag == 1)
        return node -> rchild;
    else
        return getFirst(node -> rchild);
}

我们来思考一下,原封不动的话是否可行


第一次我们带入的是D节点,程序返回的是E节点

第二次我们带入的是E节点,程序返回的是B节点

第三次我们带入的是B节点,程序返回的是E节点

后面直接就无限死循环了

答案很明显,不行

​   那我们要怎么修改呢,我们这个B节点应该要分多少种情况呢,可以通过推理知道,我们这个可以分为3种情况

1.是根节点。next = NULL

2.是左孩子,那么判断父亲右子树是否为空,如果右子树为空,next=parent;如果右子树不为空,next =getFirst(parent -> rchild)

3.是右孩子,next = parent

我们分别画出图来看

第一种情况:

第二种情况:

第三种情况:

那根据上图,我们应该大致看出来了,我们运行到"节点B"的时候,应该知道他的父类是多少才行,所以我们在结构上增加这个**

c 复制代码
typedef struct TreeNode 
{
	char data;
	struct TreeNode *lchild;
	struct TreeNode *rchild;
	struct TreeNode *parent;
	int ltag;
	int rtag;

}TreeNode;
c 复制代码
void createTree(TreeNode** T,char* temp,int* index,TreeNode* parent)
{
	char ch;
	
	ch = temp[*index];
	(*index)++;

	if( ch == '#') *T = NULL;
	else
	{
		 *T =(TreeNode*)malloc(sizeof(TreeNode));
		 (*T)->data = ch;
		 (*T)->ltag = 0;
		 (*T)->rtag = 0;
		 (*T)->parent = parent;
		createTree(&(*T)->lchild,temp,index,*T);
		createTree(&(*T)->rchild,temp,index,*T);		
	}
}

所以,我们根据以上三种情况,可以直接写出对应的代码

c 复制代码
TreeNode* getNext(TreeNode* node) 
{
	if (node -> rtag == 1)
        return node -> rchild;
    else if(node->parent == NULL)
		return NULL;
	else if(node -> parent -> rchild == node)
        return node -> parent;
	else 
	{
		if(node -> parent ->ltag == 0)
			return getFirst(node -> parent->rchild);
		else
			return	node -> parent;
	}
}

总代码

c 复制代码
/*可以输入
ABD##E##CF##G##
来进行验证
*/

#include <stdio.h>
#include <stdlib.h>
#define size 20

typedef struct TreeNode 
{
	char data;
	struct TreeNode *lchild;
	struct TreeNode *rchild;
	struct TreeNode *parent;
	int ltag;
	int rtag;

}TreeNode;


void createTree(TreeNode** T,char* temp,int* index,TreeNode* parent)
{
	char ch;
	
	ch = temp[*index];
	(*index)++;

	if( ch == '#') *T = NULL;
	else
	{
		 *T =(TreeNode*)malloc(sizeof(TreeNode));
		 (*T)->data = ch;
		 (*T)->ltag = 0;
		 (*T)->rtag = 0;
		 (*T)->parent = parent;
		createTree(&(*T)->lchild,temp,index,*T);
		createTree(&(*T)->rchild,temp,index,*T);		
	}
}

void inThreadTree(TreeNode* T, TreeNode** pre) 
{
	if(T)
	{
		inThreadTree(T->lchild,pre);
		inThreadTree(T -> rchild, pre);

		if(T->lchild == NULL)
		{
			T->ltag = 1;
			T->lchild = *pre;
		}
		if(*pre != NULL && (*pre)->rchild == NULL)
		{
			(*pre)->rtag = 1;
			(*pre)->rchild = T;
		}
		*pre = T;
        
	}

}

/* 找到最左的节点数 */
TreeNode* getFirst(TreeNode* T) 
{
	while (T -> ltag == 0)
        T = T -> lchild;
	if(T->rtag == 0)
		getFirst(T->rchild); 
    return T;

}

/* 按线索来查找 */
TreeNode* getNext(TreeNode* node) 
{
	if (node -> rtag == 1)
        return node -> rchild;
    else if(node->parent == NULL)
		return NULL;
	else if(node -> parent -> rchild == node)
        return node -> parent;
	else 
	{
		if(node -> parent ->ltag == 0)
			return getFirst(node -> parent->rchild);
		else
			return	node -> parent;
	}
}


int main(int argc, char* argv[]) 
{
	TreeNode *T;
	TreeNode* pre = NULL;
	int i=0;
	char *temp=NULL;
	TreeNode* node = NULL;
	temp=(char*)malloc(sizeof(char) * (size+1));
	gets(temp);
	createTree(&T,temp,&i,NULL);
	inThreadTree(T, &pre);
	node = getFirst(T);
    for (; node != NULL; node = getNext(node)) {
        printf("%c ", node -> data);
    }
    printf("\n");

    return 0;
}

往期回顾

1.【第一章】《线性表与顺序表》
2.【第一章】《单链表》
3.【第一章】《单链表的介绍》
4.【第一章】《单链表的基本操作》
5.【第一章】《单链表循环》
6.【第一章】《双链表》
7.【第一章】《双链表循环》
8.【第二章】《栈》
9.【第二章】《队》
10.【第二章】《字符串暴力匹配》
11.【第二章】《字符串kmp匹配》
12.【第三章】《树的基础概念》
13.【第三章】《二叉树的存储结构》
14.【第三章】《二叉树链式结构及实现1》
15.【第三章】《二叉树链式结构及实现2》
16.【第三章】《二叉树链式结构及实现3》
17.【第三章】《二叉树链式结构及实现4》
18.【第三章】《二叉树链式结构及实现5》
19.【第三章】《中序线索二叉树理论部分》
20.【第三章】《中序线索二叉树代码初始化及创树》
21.【第三章】《中序线索二叉树线索化及总代码》
22【第三章】《先序线索二叉树理论及线索化》
23【第三章】《先序线索二叉树查找及总代码》
24【第三章】《后续线索二叉树线索化理论》

相关推荐
卑微求AC16 分钟前
(C语言贪吃蛇)11.贪吃蛇方向移动和刷新界面一起实现面临的问题
c语言·开发语言
alfiy21 分钟前
Elasticsearch学习笔记(四) Elasticsearch集群安全配置一
笔记·学习·elasticsearch
向上的车轮23 分钟前
Django学习笔记十一:部署程序
笔记·学习·django
wangyue431 分钟前
c# 线性回归和多项式拟合
算法
&梧桐树夏44 分钟前
【算法系列-链表】删除链表的倒数第N个结点
数据结构·算法·链表
QuantumStack1 小时前
【C++ 真题】B2037 奇偶数判断
数据结构·c++·算法
今天好像不上班1 小时前
软件验证与确认实验二-单元测试
测试工具·算法
不灭锦鲤1 小时前
ssrf学习(ctfhub靶场)
网络·学习·安全
alfiy1 小时前
Elasticsearch学习笔记(五)Elastic stack安全配置二
笔记·学习·elasticsearch
权^1 小时前
MySQL--聚合查询、联合查询、子查询、合并查询(上万字超详解!!!)
大数据·数据库·学习·mysql