Reference books: Data structure (C language Edition) Min Wu Weimin Tsinghua University Press
1. What is a clue two fork tree
The empty left child pointer points to the predecessor of the node; the empty right child pointer points to the successor of the node. This additional pointer value is called a clue, and a two-fork tree with a clue is called a clue two-fork tree .
In different traversal sequences, each node in the binary tree usually has different precursors and successors. Therefore, the clue two fork tree is divided into the former sequence clue two fork tree, the middle order clue two fork tree and the sequential clue two fork tree 3 kinds.
According to the characteristics of the binary tree, n nodes of the two-fork tree, the chain-type storage structure, there are n+1 empty chain domain, you can use these empty chain domain to store the direct precursor to the node and direct subsequent nodes of the pointer. For this purpose, it is stipulated that when the left pointer of the node is empty (i.e. no Zuozi), the pointer points to the precursor node of the node when traversing the binary tree in some way; when the right pointer to the node is empty (that is, no right subtree), the pointer points to the successor node of the node in a way that traverses the binary tree; To avoid confusion, There is also a need to add two markers to distinguish whether the pointer is pointing to its child or its predecessor and successor.
2. Build a Clue two fork tree
The process of thread traversal is the process of traversing a binary tree. in the process of traversal, check whether the left and right pointer fields of the current node are empty, and if null, change them to a clue to the predecessor node or subsequent node .
The time complexity of traversing the binary tree is still O (n), but the constant factor is smaller than the algorithm in the previous post, and there is no need to set up a stack, after the thread has spent two fork trees. Therefore, if the two-fork tree used in the program often needs to traverse or find the precursors and successors of the linear sequence of nodes, the clue list should be used as the storage structure of the binary tree.
clues on a two-fork tree: For example, in the sequence of a binary tree, the successor of the node is either the right sign is 1, the successor directly is the right clue point, or is the first node that accesses the right subtree, that is, the leftmost node in the right subtree, and the precursor of the node has either a left sign of 1, The precursor is the node that the left clue refers to, or the last node that is accessed when traversing its left subtree, which is the lower-right node in the left subtree.
For the sake of convenience. In the form of the storage structure of the linear table, a head node is also added on the Clue list of the binary tree, and the pointer of its Lchild field points to the root node of the binary tree, and the pointer to the Rchild field points to the last node in the sequence traversal; The Lchild field pointer of the first node in the sequence of the binary tree and the pointer to the Rchild field of the last nodes point to the head node. This is like a two-fork tree to establish a two-way clue linked list, either from the first node to the subsequent traversal, or from the last node, from the predecessor to Traverse. 3. Code implementation
The following is an example of a middle order threaded binary tree. definition of 3.1 clue two fork Tree
#include <stdio.h>
#include <stdlib.h>
//#define LINK 0//pointer mark
//#define THREAD 1//clue Flag
typedef char Telemtype;
Middle order Clue two tree
typedef enum POINTERTAG {link, thread};//node's child field type, link representation is pointer, point to children node, thread representation is clue, indicating precursor or successor node
/ Supplemental: An enumerated type is a collection in which the elements (enumeration members) of a collection are named integer constants, with commas between elements
//The default value of the first enumeration member is 0 of the integral type, and the subsequent enumeration member's value is added 1 to the previous member.
//The value of the enumeration member can be set artificially, thereby customizing a range of integers.
typedef struct thrbinode{
telemtype data;
Thrbinode *lchild, *rchild;//around the child pointer
Pointertag Ltag, rtag;//around the flag}thrbinode, *thrbitree
;
3.2 sequence-cue binary tree
The process of the thread stroke is the process of modifying the null pointer during the traversal process, in order to note the sequence of access nodes in the traversal process, the attached pointer pre always points to the precursor node of the current Access node p.
The sequence traverses the binary tree T, and the sequence is threaded, Thrt point to the head node
void inorderthreading (Thrbitree T, Thrbitree &thrt) {
//Initialize the thread list, and establish a head node for it.
Thrt = (thrbitree) malloc (sizeof (Thrbinode));
Thrt->ltag = Link;
Thrt->rtag = Thread;
Thrt->rchild = thrt;//Right pointer back, because if T is an empty tree, it will only point to the following if statement, then Thrt->rchild
if (! T) {//If the binary tree is an empty tree, then the thrt->lchild pointer returns
thrt->lchild = Thrt;
Thrt->rchild = thrt;//Right pointer anaphora
}else{
thrt->lchild = T;
Thrbinode *pre = Thrt;//pre pointer always points to the precursor node of the current node
inthreading (T, pre);
Continue to add a thread to the last node
at this point the pre should point to the last node
pre->rtag = Thread;
Pre->rchild = thrt;//last node rchild field pointer back to
thrt->rchild = pre;//header node rchild field pointer to last node
}
}
The middle sequence traversal carries on the middle order thread (left, root, right)
void inthreading (Thrbitree t, Thrbitree &pre) {
if (t) {
inthreading (t-> Lchild, pre);//Zoozi tree cue
if (! T->lchild) {//The left child of the current node is empty
T->ltag = Thread;
T->lchild = pre;
} else{
t->ltag = Link;
}
if (!pre->rchild) {//The right child of the predecessor node is an empty
Pre->rtag = Thread;
Pre->rchild = T;
} else{
pre->rtag = Link;
}
Pre = T;
Inthreading (T->rchild, pre);//Right subtree cue
}
}
3.3 sequence traversal clue two fork Tree
T-point head node, lchild chain field pointer pointing to binary tree root node
//middle sequence traversal print binary clue Tree T (non-recursive algorithm)
void Inordertraverseprint (Thrbitree t) {
Thrbinode *p = t->lchild;//p point to root node
while (P!= T) {//empty tree or traversal end, p = = T while
(P->ltag = Link) {
p = P->lch ILD;
}
At this point, p points to the first node (the leftmost node) in the ordinal traversal sequence,
printf ("%c", p->data);//print (access) the node whose left subtree is empty while
(P->rtag = = Thread & & P->rchild!= T) {
p = p->rchild;
printf ("%c"), p->data);//Access subsequent nodes
}//When the rchild of the point of
P refers to a child node instead of a clue, P's successor should be the leftmost node of its right subtree, the first one to be accessed when traversing its right subtree
p = p->rchild;
}
printf ("\ n");
}
3.4 Create two fork tree
A binary tree, '. ', is established using the first order sequence. Represents an empty tree
//test Case 1:ABC. De.g.. f...#
//test Case 2:-+a. *b.. -C.. D.. /e.. F.. #
void Createbitreebypreorder (Thrbitree &t) {
//Enter the value of the node in the binary tree (a character) by first order, the dot character denotes an empty tree, and the two-fork tree represented by the two-fork list is constructed
/ Note: If the number of characters entered (excluding the # number) is n, then the corresponding empty tree point number should have n+1
char ch;
scanf ("%c", &ch);
if (ch!= ' # ') {
if (ch = = '. ') {
T = NULL;
} else{
T = (Thrbinode *) malloc (sizeof (Thrbinode));
T->data = ch;
Createbitreebypreorder (t->lchild);
Createbitreebypreorder (T->rchild);}}
3.5 Demo
Test Cases
two fork tree:
Test input:-+a. *b.. -C.. D.. /e.. F.. #
corresponding middle order clue two fork tree:
void Main () {
thrbitree T;
printf ("Enter the values of the nodes in the binary tree in order of precedence, the empty tree in spaces, end with #: \ n");
Createbitreebypreorder (T);//Establish two fork tree
thrbitree thrt;
Inorderthreading (t, thrt);//The sequence of the two-fork tree T is
inordertraverseprint (THRT);//in-sequence traversal of the binary clue tree (through the clue list, just like accessing the linear table)
// Of course, the previous not according to the clue, directly according to the structure of the binary tree traversal can still (level, first order, after, in order)
}