clue binary tree
1 Introduction
The clue binary tree is mainly for the convenience of determining the direct predecessor and direct successor of an element of the binary tree. It utilizes the empty chain field of the node on the basis of the chain binary tree, and is used to store the predecessor and successor information of the node. In order to distinguish whether the node chain field points to its left (right) child or to its predecessor (successor), the node structure of the original chained binary tree is improved:
Among them, when the lchild chain domain points to the left child, lTag= 0; when the lchild chain domain points to its predecessor, lTag= 1. rchild is similar.
A binary tree using this storage structure (actually a binary linked list) is a clue binary tree. The process of turning a chained binary tree into a threaded binary tree is threaded. That is, the empty chain field of the node in the chained binary tree is modified to point to the predecessor or successor of the node.
A binary tree as shown below:
2. Code
Status inOrderThreading(binaryThrTree &thrT, binaryThrTree T){ //thrT is the head node after threading, T is the binary tree to be threading binaryThrTree pre; thrT = new binaryThrNode;//New head node if(!thrT) exit(-1); thrT->lTag = Link; //The left link domain of the head node is marked as a pointer thrT->rTag = Thread; //The right chain domain of the head node is marked as a thread thrT->rchild = thrT; //The right chain field of the head node is marked as a clue pointing to the last node visited by in-order traversal (initialized to point to the node itself first) if(!T)thrT->lchild = thrT;//If the binary tree is empty, point the left chain domain of the head node to the head node else{ thrT->lchild = T; //If the binary tree is not empty, point the left chain field of the head node to the root of the binary tree pre = thrT;//Record the node just visited InThreading(T ,pre);//Threaded binary tree pre->rchild = thrT;//After the threading is over, pre saves the last node visited after the in-order traversal, and then makes the right chain domain of the node point to the head node pre->rTag = Thread;//Identified as a thread thrT->rchild = pre;//Point the right chain field of the head node to the last visited node after the in-order traversal } return 1; }
void InThreading(binaryThrTree p, binaryThrTree &pre){ if(p){ InThreading(p->lchild, pre);//Left subtree of the current node if(!p->lchild){p->lTag = Thread;p->lchild = pre;}//Precursor clue if(!pre->rchild){pre->rTag = Thread;pre->rchild = p;}//Subsequent thread pre = p; InThreading(p->rchild, pre);//Thread the right subtree of the current node } }
After the binary tree is threaded, it can be traversed:
Status InOrderTraverse_Threads(binaryThrTree thrT){ binaryThrTree p = thrT->lchild;//Find the root node of the binary tree while(p != thrT){//The binary tree is empty or p points to the head node when the threaded binary tree is traversed while(p->lTag == Link) p = p->lchild; cout<<p->data<<" ";//Access the node whose left subtree is empty while(p->rTag == Thread && p->rchild!= thrT){//Access the successor node according to the clue p = p->rchild; cout<<p->data<<" "; } p = p->rchild; } return 1; }
The complete code is as follows:
// binaryThrTree.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include <string> #include <iostream> using namespace std; typedef string tElemType; typedef int Status; typedef enum PointerTag{Link, Thread}; typedef struct binaryThrNode{ tElemType data; struct binaryThrNode *lchild, *rchild; PointerTag lTag, rTag; }binaryThrNode, *binaryThrTree; Status createthrTree(binaryThrTree &thrT){ //create a thread binary tree in pre-order. //after this work finished, the attributes lTag and rTag of this thread binary tree is not initialised. string starts; cin>>starts; if(starts == "#") thrT = NULL; else{ thrT = new binaryThrNode; if (!thrT) exit(-1); thrT->data = starts; thrT->lTag = Link; thrT->rTag = Link; createthrTree(thrT->lchild); createthrTree(thrT->rchild); } return 1; } Status inOrderTraverse(binaryThrTree T){ if(T){ inOrderTraverse(T->lchild); cout<<(T->data)<<" "; inOrderTraverse(T->rchild); } return 1; } void InThreading(binaryThrTree p, binaryThrTree &pre){ if(p){ InThreading(p->lchild, pre); if(!p->lchild){p->lTag = Thread;p->lchild = pre;} if(!pre->rchild){pre->rTag = Thread;pre->rchild = p;} pre = p; InThreading(p->rchild, pre); } } Status inOrderThreading(binaryThrTree &thrT, binaryThrTree T){ binaryThrTree pre; thrT = new binaryThrNode; if(!thrT) exit(-1); thrT->lTag = Link; thrT->rTag = Thread; thrT->rchild = thrT; if(!T)thrT->lchild = thrT; else{ thrT->lchild = T; pre = thrT; InThreading(T ,pre); pre->rchild = thrT; pre->rTag = Thread; thrT->rchild = pre; } return 1; } Status InOrderTraverse_Threads(binaryThrTree thrT){ binaryThrTree p = thrT->lchild; while(p != thrT){ while(p->lTag == Link) p = p->lchild; cout<<p->data<<" "; while(p->rTag == Thread && p->rchild!= thrT){ p = p->rchild; cout<<p->data<<" "; } p = p->rchild; } return 1; } int _tmain(int argc, _TCHAR* argv[]) { binaryThrTree T = new binaryThrNode; if(!T) exit(-1); cout<<"Try to create a thread binary tree..."<<endl; createthrTree(T); cout<<"creation is finished!"<<endl; cout<<"Try to traverse it:"<<endl; inOrderTraverse(T); binaryThrTree thrT; cout<<endl<<"Try to thread the binary thread tree..."<<endl; inOrderThreading(thrT, T); cout<<"Try to traverse the binary thread tree with threads:"<<endl; InOrderTraverse_Threads(thrT); delete thrT; delete T; system("pause"); return 0; }
The effect is as follows: