Reference books: Data structure (C language Edition) Min Wu Weimin, Tsinghua University Press 1. Two fork Tree definition
The two-forked tree (Binary) is a finite set of nodes, which is either empty, or consists of a single root node and two disjoint two-tree trees called the Saozi right subtree.
The above definition of the two fork tree is also a recursive way, the binary tree is also a tree, it is a special kind of tree, each node can only have a maximum of two Shang trees, and its subtree also satisfies the definition of binary tree, is either empty, or a root node and two Saozi right subtree of two fork tree composition.
The two-pronged tree is characterized by a maximum of two children per node, or, in a binary tree, there is no more than 2 nodes, and the binary tree is an ordered tree (the tree is an unordered tree), the order of its subtree can not be reversed, therefore, the binary tree has five different forms, see the following figure:
Two The nature of the tree:
1. A maximum of 2I-1 nodes (i≥1) on layer I of the two fork tree.
2. The two-fork tree with a depth of K has a maximum of 2k-1 nodes (k≥1).
3. In any binary tree, the number of leaf nodes (that is, the node of the degree of 0) equals 2 of the knot points plus 1. namely n0=n2+1.
4. The complete binary tree with n nodes has a height of log2 (n) down the whole +1 or log2 (n+1) upwards.
5. If you put a complete binary tree with n nodes from top to bottom, the node number is 1,2,...,n from left to right, and then the nodes in the two-fork tree are stored sequentially in a one-dimensional array by this number, and the short node numbered J (1≤j≤n) is as follows:
(1) If the J=1, the node j is the root node, no parents, otherwise J's parents are (J/2) downward rounding;
(2) If 2j≤n, then the left child of the node J is 2j, otherwise there is no left child. The node that satisfies the 2j>n is the leaf node;
(3) If 2j+1≤n, then the right child of the knot J is 2j+1, otherwise there is no right child;
(4) If the node J serial number is odd and does not equal 1, then its left brother is j-1;
(5) If the node J serial number is even and not equal to N, its right brother is j+1;
(6) the layer (level) of Node J is (LOG2J) down to +1;
Add:
6. A complete binary tree with N nodes (N/2) takes up the entire leaf node.
7. Given a sequence of precursors and a sequence of sequences, or given a sequence of sequences and sequences, a binary tree can be uniquely determined. 2. Two-fork Tree storage 2.1 Sequential storage structure
#define MAX_TREE_SIZE
typedef char Telemtype;
typedef telemtype SQBITREE[MAX_TREE_SIZE];
Sqbitree Tree;
For node Tree[i], parent node: TREE[I/2]
Left child node: Tree[2*i]
Right child knot: tree[2*i+1]
For a general two-fork tree, a number of virtual nodes in the binary tree are made into complete binary trees, which are then stored in the above method.
For a binary tree, if the use of sequential storage, when it is a complete binary tree, more convenient, if not a complete binary tree, will waste a large number of storage storage units . The worst of the incomplete binary tree is all only the right branch, set a height of k, you need to occupy 2k-1 storage unit, and actually only k elements, the actual only K storage unit. Therefore, for the incomplete binary tree, it is advisable to use the following chain-type storage structure.
2.2-Chained storage structure
2.2.1 Dynamic two-fork linked list
typedef char Telemtype;
Dynamic binary chain table
typedef struct bitnode{
telemtype data;
struct Bitnode *lchild, *rchild;
} Bitnode, *bitree;
For a binary tree, if the use of binary chain table storage, when the binary tree is not a complete binary tree, more convenient, if the full binary tree, will occupy more storage units (the location of the pointer).
If a binary tree has n nodes, when the binary chain table is used as the storage structure, there are 2n pointer fields, in which only the n-1 pointer points to the left and right children, and the rest of the n+1 pointer is empty, and is wasted, but we can use these empty-link fields to store other useful information. To get another chain-type storage structure---- clue list, will be introduced in the future blog.
2.2.2 Static two-fork linked list
#define MAXSIZE
typedef char Telemtype;
typedef struct{
int llink;
Telemtype data;
int rlink;
} Binode;
typedef binode bitree[maxsize+1];//Subscript 0 Units empty
3. Two-fork tree static chain table storage and traversal of the implementation
Traversal: System access to the nodes in the data structure, each node is exactly accessed once.
The process of traversing a binary tree is actually the process of forming a linear sequence of nodes in a two-fork tree, or linearization of a two-fork tree .
Hierarchical traversal, forward traversal, middle sequence traversal, sequential traversal
Test instance:
test by First sequence input: ABC.. De.g.. f...#, dot number for empty tree, #为输入结束符 3.1 define static binary chain list
#include <stdio.h>
#define MAXSIZE
typedef char Telemtype;
typedef struct{
int llink;
Telemtype data;
int rlink;
} Binode;
typedef binode bitree[maxsize+1];//Subscript 0 Units empty
3.2 Recursive algorithm for creating two-fork tree by First order sequence input
Enter the value of the node in the binary tree (a character) in order of precedence, the dot character denotes an empty tree, the two-forked tree T
void Createbitree (bitree &t, int &root, int &i) represented by the two-fork list
Telemtype E;
scanf ("%c", &e);
if (e!= ' # ') {
if (e!= '. ') {//Input current node is not "empty tree", it is a real knot
. T[i].data = e;
T[i].llink = 0;
T[i].rlink = 0;
root = i;
Createbitree (T, T[root].llink, ++i);
Createbitree (T, T[root].rlink, ++i);
else{
root = 0;//Enter the current node is "Empty Tree", is a virtual node, then the chain pointing to it is 0
i--;//static list subscript fallback, because the empty tree does not enter the table, only the real node into the table}
}
recursive algorithm for 3.3 first-order traversing binary tree
First-order traversal of the binary tree (root, left, right) (recursive algorithm)
void Preorderprint (Bitree T, int root) {
if (root) {//root node is not empty
printf ('%c ', T[root]. data);
Preorderprint (T, t[root].llink);
Preorderprint (T, T[root].rlink);
}
non-recursive algorithm for 3.4 first-order traversing binary tree
First-order traversal of binary tree (root, left, right) (non-recursive algorithm)
void PreOrderPrint2 (Bitree T, int root) {
//binode s[maxsize];//maintains a stack that records traversed nodes
int s[maxsize];//maintains a stack that records the traversal of the node
int top = 0;//points to the next position of the topmost element on the stack, at the very beginning of the first = 0
int pointer = root;// Pointer to the root node of the current layer while
(pointer | | top) {
if (pointer) {//root node is not empty
printf ("%c", t[pointer].data);
S[top++] = t[pointer];//root node into stack
s[top++] = pointer;//root node into stack
pointer = t[pointer].llink;//Find root node's left child
} else{//root node is empty
//binode Topelem = s[--top];//stack top element out stack, that is, the root node of the upper layer
//pointer = topelem.rlink;
int topelempt = s[--top];//stack top element out stack, that is, the root node of the previous layer
pointer = T[topelempt].rlink;
}}
Demonstrate:
void Main () {
bitree tree;
int root = 1;//The location of the root node
printf ("Please enter the binary tree in order of the first sequence to the end of the #, empty tree with the point number instead: \ n");
int pos = 1;//control adds the position of the static array
Createbitree (tree, root, pos);
printf ("First-order traversal-print binary tree (recursive algorithm): \ n");
Preorderprint (tree, root);
printf ("\ n");
printf ("First-order traversal-print binary tree (non-recursive algorithm): \ n");
PreOrderPrint2 (tree, root);
printf ("\ n");
}
recursive algorithm for 3.5 sequential traversal binary tree
Sequence traversal binary tree (left, Root, right) (recursive algorithm)
void Inorderprint (Bitree t, int root) {
if (root) {//root node is not empty
inorderprint T, t[ Root].llink);
printf ("%c", t[root].data);
Inorderprint (T, T[root].rlink);
}
non-recursive algorithm for 3.6-order traversing binary tree
Sequence traversal binary tree (left, Root, right) (non-recursive algorithm)
void InOrderPrint2 (Bitree T, int root) {
//binode s[maxsize];//maintains a stack to record traversed nodes
int s[maxsize];//maintains a stack that records the traversal of the node
int top = 0;//points to the next position of the topmost element on the stack, at the beginning of the top-level = 0
int pointer = Root;//pointer point to the root node of the current layer While
(pointer | | top) {
if (pointer) {//root node is not empty
//s[top++] = t[pointer];//root node into stack
s[top++] = pointer;// root node into stack
pointer = t[pointer].llink;//to find the root node of the left child
}else{//root node is empty
//binode Topelem = s[--top];//stack top elements out of the stack, That is, the root node of the upper layer
//printf ("%c", topelem.data);
pointer = Topelem.rlink;
int topelempt = s[--top];//stack top element out stack, that is, the root node of the upper layer
printf ("%c", t[topelempt].data);
pointer = T[topelempt].rlink;
}
}
Demonstrate:
void Main () {
bitree tree;
int root = 1;//The location of the root node
printf ("Please enter the binary tree in order of the first sequence to the end of the #, empty tree with the point number instead: \ n");
int pos = 1;//control adds the position of the static array
Createbitree (tree, root, pos);
printf ("Sequential traversal print binary tree (recursive algorithm): \ n");
Inorderprint (tree, root);
printf ("\ n");
printf ("Sequential traversal print binary tree (non-recursive algorithm): \ n");
InOrderPrint2 (tree, root);
printf ("\ n");
}
recursive algorithm for 3.7 sequence traversal binary tree
Subsequent traversal of the binary tree (left, right, root) (recursive algorithm)
void Postorderprint (Bitree t, int root) {
if (root) {//root node is not empty
postorderprint T, T[root].llink);
Postorderprint (T, t[root].rlink);
printf ("%c", T[root].data);
}
non-recursive algorithm for 3.8 sequence traversal binary tree
Subsequent traversal of the binary tree (left, right, root) (non-recursive algorithm)
void PostOrderPrint2 (Bitree T, int root) {
//binode s[maxsize];//maintains a stack to record the traversed nodes
int s[maxsize];//maintains a stack that records the traversal of the node pointer
int top = 0;//point to the next position of the topmost element on the stack, at the very beginning of the first = 0
int pointer = root;// Pointer to the root node of the current layer while
(pointer | | top) {
if (pointer) {///root node is not empty
//s[top++] = t[pointer];//root node into stack
s[top + +] = pointer;//root node pointer into stack
pointer = t[pointer].llink;//Find the left child of root node
}else{//root node is empty
//binode Topelem = s[top-1] //Get the top element of the stack, that is, the root node
int topelempt = s[top-1];//Gets the stack top element pointer, which is the root node pointer on the previous layer
(Topelempt > 0) {// The right subtree of the current layer root node has not been accessed, the right subtree is accessed, and the "right subtree has been traversed" flag
pointer = t[topelempt].rlink;
S[TOP-1] =-s[top-1];
} else{
//binode topelem = s[--top];//stack top element out stack, that is, the root node of the previous layer
topelempt =-topelempt;//restore
printf ("%c", t[ Topelempt].data);
top--}}}}
Demonstrate:
void Main () {
bitree tree;
int root = 1;//The location of the root node
printf ("Please enter the binary tree in order of the first sequence to the end of the #, empty tree with the point number instead: \ n");
int pos = 1;//control adds the position of the static array
Createbitree (tree, root, pos);
printf ("Sequence traversal print binary tree (recursive algorithm): \ n");
Postorderprint (tree, root);
printf ("\ n");
printf ("Sequence traversal print binary tree (non-recursive algorithm): \ n");
PostOrderPrint2 (tree, root);
printf ("\ n");
}
3.9 Non-recursive algorithm of traversing binary tree by hierarchy
typedef binode QELEMTYPE;
typedef struct{
//qelemtype data[20];
Qelemtype data[20];
int f;//points to the team head element
int r;//pointing to the next position on the tail element
}sqqueue;
Initializes an empty queue
void Initqueue (Sqqueue &q) {
q.f = Q.R = 0;
}
Traversing the binary tree (from top to bottom, left to right)
void Hierarchicaltraverseprint (Bitree T, int root) {
Sqqueue q;//maintains a queue by hierarchy, from top to bottom, From left to right storage of two fork tree nodes (in fact, the breadth-first search algorithm to achieve hierarchical traversal)
initqueue (Q);
Binode queue[20];
Root node
Q.DATA[Q.R] = T[root];
q.r++;
while (q.f!= q.r) {
//First descending team head element's left child (real node) queue
if (q.data[q.f].llink) {
Q.DATA[Q.R] = T[q.data[q.f].llink];
q.r++;
}
Join the right child (real node) of the team head element
if (q.data[q.f].rlink) {
Q.DATA[Q.R] = T[q.data[q.f].rlink];
q.r++;
}
Print (access) the team head element and move it out of the team
printf ("%c", q.data[q.f].data);
q.f++;
}
Demonstrate:
void Main () {
bitree tree;
int root = 1;//The location of the root node
printf ("Please enter the binary tree in order of the first sequence to the end of the #, empty tree with the point number instead: \ n");
int pos = 1;//control adds the position of the static array
Createbitree (tree, root, pos);
printf ("Traversing a hierarchical print binary tree (non-recursive algorithm): \ n");
Hierarchicaltraverseprint (tree, root);
printf ("\ n");
}
4. Traversing the binary tree application 4.1 to find the depth of the two-fork tree
To find the depth of the binary tree
int getbitreedepth (bitree T, int root) {
if (!root)//root node is empty tree return
0;
int lefttreedepth = getbitreedepth (T, t[root].llink);
int righttreedepth = getbitreedepth (T, t[root].rlink);
return lefttreedepth > Righttreedepth? (lefttreedepth + 1): (righttreedepth + 1);
}
Demonstrate:
void Main () {
bitree tree;
int root = 1;//The location of the root node
printf ("Please enter the binary tree in order of the first sequence to the end of the #, empty tree with the point number instead: \ n");
int pos = 1;//control adds the position of the static array
Createbitree (tree, root, pos);
int depth = Getbitreedepth (tree, root);
printf ("The depth of the two fork tree is:%d\n", depth);
}
4.2 knot points for binary tree
Find the knot point of the binary tree
int getbitreesize (bitree T, int root) {
if (!root) return
0;
int lefttreesize = Getbitreesize (T, t[root].llink);
int righttreesize = Getbitreesize (T, t[root].rlink);
Return lefttreesize + righttreesize + 1;
}
Demonstrate:
void Main () {
bitree tree;
int root = 1;//The location of the root node
printf ("Please enter the binary tree in order of the first sequence to the end of the #, empty tree with the point number instead: \ n");
int pos = 1;//control adds the position of the static array
Createbitree (tree, root, pos);
int size = Getbitreesize (tree, root);
printf ("The node of the two fork tree is:%d\n", size);
}
4.3 The number of leaf nodes of the binary tree
First-order traversal method to find the number of leaf nodes of the binary tree
int getbitreeleafnodesnum (bitree T, int root) {
if (!root) return
0;
The else{//root node is not an empty tree
if (! T[root].llink &&! T[root].rlink) {//If the left and right children of the current root node are NOT null return
1;
}
int lefttreeleafnodesnum = Getbitreeleafnodesnum (T, t[root].llink);
int righttreeleafnodesnum = Getbitreeleafnodesnum (T, t[root].rlink);
return lefttreeleafnodesnum + righttreeleafnodesnum;
}
}
Demonstrate:
void Main () {
bitree tree;
int root = 1;//The location of the root node
printf ("Please enter the binary tree in order of the first sequence to the end of the #, empty tree with the point number instead: \ n");
int pos = 1;//control adds the position of the static array
Createbitree (tree, root, pos);
int leafnodesnum = Getbitreeleafnodesnum (tree, root);
printf ("The leaf knot of the two-fork tree is:%d\n", leafnodesnum);
}