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

文章目录


回顾查找首节点

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

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【第三章】《后续线索二叉树线索化理论》

相关推荐
泉崎8 分钟前
11.7比赛总结
数据结构·算法
你好helloworld10 分钟前
滑动窗口最大值
数据结构·算法·leetcode
QAQ小菜鸟25 分钟前
一、初识C语言(1)
c语言
hong16168835 分钟前
跨模态对齐与跨领域学习
学习
何曾参静谧40 分钟前
「C/C++」C/C++ 之 变量作用域详解
c语言·开发语言·c++
互联网打工人no144 分钟前
每日一题——第一百二十一题
c语言
AI街潜水的八角1 小时前
基于C++的决策树C4.5机器学习算法(不调包)
c++·算法·决策树·机器学习
白榆maple1 小时前
(蓝桥杯C/C++)——基础算法(下)
算法
阿伟来咯~1 小时前
记录学习react的一些内容
javascript·学习·react.js
JSU_曾是此间年少1 小时前
数据结构——线性表与链表
数据结构·c++·算法