C data structures and algorithms - the basis of consolidation - Tree-06: threaded binary (a)

线索二叉树的原理和实现代码

About Binary Tree can view the following article:

C data structures and algorithms - the basis of consolidation - Tree-02: the establishment of binary tree traversal and Different

Specific preamble sequence and the way of clues, you can refer to the following article:

C data structures and algorithms - the basis of consolidation - Tree-07: threaded binary (two)

0x01. Clues to the origin of a binary tree

In general binary tree , the leaf nodes or only one child node there will be a lot of empty pointer fields, these spaces have been created, but has not been effectively utilized, resulting in a waste of space .

Solution:

The left child of a null pointer points to the predecessor parent node and set Ltag flag variable to indicate the left child is pointing to a precursor or a real presence.

The right child of the null pointer successor parent node and set Rtag flag variable to indicate the right child is pointing to a successor or real.

Related concept note:

Precursors : when following a particular binary tree traversal order traversal, the traversal of a node on a node.

Subsequent : when following a particular binary tree traversal order traversal, a node next to node traversal.

Clue : a pointer points to the predecessor and successor called clues.

Threaded binary : binary add clues.

Clues : a binary tree called clues on the course of a null pointer plus clues.

0x02. Threaded binary structure

The difference is that ordinary binary tree, binary tree structure clues in more than a Ltag and Rtag flag variable to indicate the identity of the child's left and right children.

In addition, threaded binary cue process, the need for a global pre pointer to the elements just visited.

typedef struct TreeNode
{
	char data;
	struct TreeNode* Left;
	struct TreeNode* Right;
	int Ltag;//用于线索化的标志变量  左为1表示前驱 右为1表示后继,0表示自身是树中元素
	int Rtag;
}TreeNode,*BinTree;//定义了这个结构体为 TreeNode ,这个二叉树指针为 BinTree
BinTree pre;

0x03. Build threaded binary

Build threaded binary and establish common binary tree is basically the same, the difference is that each additional clues to binary tree node, you need to sign about variable initialization.

Specific establish similar establishment code and ordinary binary tree, reference chapter: point of this visit

Description: The binary tree of clues which establish a way of traversing not conflict, is still essentially a binary tree and established order is the same.

//二叉树的建立:递归实现,先序遍历的创建方法
//注意此处BT为指针的指针,因为没有返回值,所以要把二叉树的指针完全改变掉,需要指针的指针
//str为传入的字符串,该字符串用于创建二叉树的数据域
//n为当前创建节点数据域时使用到str的位数
//返回值为记录二叉树创建完毕后,使用了多少字符
int CreateTree(BinTree *BT,char *str,int n)
{
	printf("创建二叉树第  %d  个节点   ", n);
	char ch = str[n];//每次使用一个字符赋值数据域
	printf("%c\n", ch);//输出该数据
	n++;
	if (ch != '\0')//字符串没完就一直创建
	{
		if (ch == '#')//如果遇到字符 # ,说明下方没有了,是叶节点
		{
			*BT = NULL;//代表二叉树指针为空
		}
		else
		{
			*BT = (BinTree)malloc(sizeof(TreeNode));//*BT代表二叉树指针的值,BinTree表示这是一个指针,大小为一个二叉树结构体
			if (!*BT)
			{
				exit(-1);//若分配空间失败,异常退出
			}
			(*BT)->data = ch;
			(*BT)->Ltag = 0;//注意一定要有这个初始化步骤
			(*BT)->Rtag = 0;
			n=CreateTree(&(*BT)->Left,str, n);//取指针的地址给此函数的第一个参数,因为此参数为二级指针
			n=CreateTree(&(*BT)->Right, str, n);
		}
	}
	return n;
}

 

0x04. In order threaded threaded binary

Clues can be carried out in various sequences, but the sequence of clues and traversal order can only be one correspondence.

//中序遍历线索化
void inThreading(BinTree BT)
{
	if(BT)
	{
		inThreading(BT->Left);
		if (!BT->Left)//若左孩子不存在,则左孩子线索化,指向前驱节点,即上一个访问过的节点
		{
			BT->Ltag = 1;
			BT->Left = pre;
		}
		if (pre && !pre->Right)//当遍历到BT时,若它的前驱pre存在,且前驱右孩子不存在,那么前驱的右孩子指向BT,即BT为pre的后继
		{
			pre->Rtag = 1;
			pre->Right = BT;
		}
		pre = BT;//当准备遍历下一个节点时,用pre保存当前的节点
		inThreading(BT->Right);//继续中序遍历完成线索化
	}
}

0x05. Clues in order binary tree traversal

And the binary sequence corresponding threaded manner.

//中序遍历线索二叉树,非递归实现
void InOrderThreading(BinTree BT)
{
	BinTree p = BT;//让p指向根节点
	while (p)
	{
		while (p->Ltag == 0)
		{
			p = p->Left;
		}//首先遍历到中序遍历第一个开始的节点
		printf("%c -> ", p->data);//打印其数据
		while (p->Rtag == 1&&p->Right)//如果右孩子是线索,那么一直遍历至右孩子,因为右孩子指向后继
		{
			p = p->Right;
			printf("%c -> ", p->data);
		}//右孩子不是线索了,说明右孩子存在,左孩子刚遍历到了,所以接着右孩子的遍历,然后开始下一轮的遍历
		p = p->Right;
	}
}

0x06. Plus a head node threaded binary

Increase before the binary tree root a head node, its left child point to the root node, right child points to the last node in order traversal, so that a binary tree is like a doubly linked list, either from scratch traverse, but also from the tail traversal.

Clues:

//增加头结点的中序线索化,Head为二级指针,指向指针的指针,目的是真正改变一级指针的内容
void InOrderThreading(BinTree* Head, BinTree BT)
{
	*Head =(BinTree)malloc(sizeof(TreeNode));//给头结点分配空间
	(*Head)->Ltag = 0;//左孩子是根结点
	(*Head)->Rtag = 1;//右孩子是线索
	(*Head)->Right = (*Head);//右孩子先指向自身,防止原二叉树为空
	if (!BT)//二叉树为空
	{
		(*Head)->Left = (*Head);//左孩子也指向自身
		return;
	}
	pre = (*Head);//前指针指向头结点
	(*Head)->Left = BT;
	inThreading(BT);//开始普通的中序线索化二叉树
	//此时二叉树中序序列的第一个结点的左孩子指向头结点
	//结束普通的线索化后,此时的pre指针指向最后一个元素
	pre->Right = *Head;
	pre->Rtag = 1;
	(*Head)->Right = pre;
	//现在整个二叉树就是一个双向链表,既可以从头结点开始往后遍历,也可以从中序序列最后一个结点开始往前遍历
}

Traversal:

//有头结点的中序遍历线索二叉树,此时的BT是头结点
void InOrderThreading1(BinTree BT)
{
	BinTree p = BT->Left;//让p指向根节点
	while (p!=BT)//循环到尾部时,因为尾部右孩子指向头结点,所以,p等于头结点的时候遍历完成
	{
		while (p->Ltag == 0)
		{
			p = p->Left;
		}//首先遍历到中序遍历第一个开始的节点
		printf("%c -> ", p->data);//打印其数据
		while (p->Rtag == 1 && p->Right!=BT)//此处右孩子的条件应为不等于BT
		{
			p = p->Right;
			printf("%c -> ", p->data);
		}//右孩子不是线索了,说明右孩子存在,左孩子刚遍历到了,所以接着右孩子的遍历,然后开始下一轮的遍历
		p = p->Right;
	}
}

Lead main function node test code:

int main()
{
	BinTree BT;//注意BT为指针
	int k;//记录创建函数的返回值
	char str[100];
	printf("\n\n**********\t请输入一串字符用于创建二叉树:");
	gets_s(str);
	k = CreateTree(&BT, str, 0);
	printf("\n\n**********\t二叉树创建成功!!!共使用了  %d  个字符",k);
	BinTree Head;
	printf("\n\n**********\t开始中序线索化该二叉树......");
	InOrderThreading(&Head,BT);
	printf("\n\n**********\t线索化成功!!!");
	printf("\n\n**********\t开始该线索二叉树的中序遍历......");
	printf("\n\n**********\t中序遍历结果为:");
	InOrderThreading1(Head);
	
}

Test Data: AB # D ## C ##

0x07. Doubts and insights

1. Binary Tree null pointer should be limited, why only these null pointer on the whole tree will be able to clue clues to reach each node can find a successor?

A: Features preorder before observed, the children return from left to print node information, the right to return the child ended with the pace, pay attention to print this node is the real traverse to the node, it is how to return the children left it, when a child is left empty, or partially left the children have completed the entire process of function calls, if the child is left empty, then just left the child points to the predecessor, the child if left partially completed function call, then left the child is the child's left and right children returned after the completion of the entire call, and so on, will always find the root of return: return from a leaf node, it can be understood that any node to traverse around children are present, so a node and the next node free of a certain part of it's on, that is not all there is about children, so that children there are two nodes will have the presence of the successor and predecessor pointers. Furthermore, you can see click quantitative relationship therebetween: for a binary tree of n nodes, a total of 2n pointer field, a total of n nodes of branches n-1, where it 2n- (N-1) = n + 1 pointers actually null pointer field, but in fact the n-1 pointer points to complete the relationship tree (even if a node has two children, can be traversed in order according to Looking down order, find the successor precursor), wherein a first node traversed no precursor, the last node traversed no successor. So, in fact null pointer domain is sufficient.

2. Under what circumstances threaded binary?

A: When often find the need to traverse junctions or points, may be used, it is far less than the time complexity of the recursion method.

3. understand the clues in order traversal, in fact, before the sequence, after, about the same principle.

 

Published 19 original articles · won praise 7 · views 414

Guess you like

Origin blog.csdn.net/ATFWUS/article/details/104291897
Recommended