Hierarchy Relationship Structure: Tree
Tree concept: A tree is a collection of n nodes
A node is called the root node, a is the parent node of B C D, and vice versa, and B C D is the respective sibling node respectively.
Degree of node: the number of sub-trees of a node is called the degree of that node
Degree of the tree: the degree of the largest node in a tree is called the degree of the tree
leaf node or end node: a node of degree 0 is called a leaf node
Hierarchy of nodes: Starting from the root, the root is the 1th layer, the child node of the root is the 2nd layer, and so on
The height or depth of a tree: the maximum level of nodes in a tree
But it's not that intuitive.
(A (B (E)), (C (F (J)), (G (k,l))), (D (H), (I (M,n))))
Simple can be divided into:
Unordered tree: There is no sequential relationship between the child nodes of any node in the tree, which is called the unordered tree, also known as the free tree
Ordered tree: There is a sequential relationship between the sub-nodes of any node in the tree, which is called an ordered tree.
Binary tree: A tree with up to two subtrees per node called a binary tree
Two special two-fork trees:
Complete binary tree: Except for the last layer, the number of nodes on each layer reaches the maximum, and only a few nodes on the right are missing on the last layer
Full two tree: Except for the last layer without any child nodes, all nodes on each layer have two sub-nodes or 0 subnodes of two fork tree, full two fork tree must be completely binary tree
According to the definition of binary tree, it can be known that it has the following properties:
(1) In a binary tree, the total number of nodes in layer I has 2i-1 nodes.
(2) The two-fork tree with a depth of K has a maximum of 2k-1 nodes (k>=1) with a minimum of K nodes.
(3) For a binary tree, if its leaf node is n0, and the number of nodes with a degree of 2 is N2, then n0=n2+1
(4) The depth k of a complete binary tree with N nodes is: k=[log2n]+1
Binary Tree Storage:
Sequential storage structure
Chained storage structure
Normal operation of a binary tree:
1. Defining a binary chain structure
2. Initialize binary tree
3. Add nodes to two fork tree
4. Get binary tree left and right sub-trees
5. Get binary Tree status
6. Find in a binary tree
7. Empty the binary tree
#include <stdio.h>#include<stdlib.h>#defineQueue_maxsize 50typedefCharDATA;//defining element TypestypedefstructChaintree//Defining binary tree node types{data data; //element Data structChaintree *left;//Left Dial hand tree node pointer structChaintree *right;//Right sub-tree node pointer}chainbintree; Chainbintree*bintreeinit (Chainbintree *node)//Initialize the root node of a binary fork.{ if(Node!=null)//if the binary root node is not empty. returnnode; Else returnNULL;}intBintreeaddnode (Chainbintree *bt,chainbintree *node,intN//add data to two fork tree//BT is the parent node, node is a child node, n=1 means adding the left subtree, and n=2 means adding the right sub-tree{ if(bt==NULL) {printf ("parent node does not exist, please set parent node!\n first ."); return 0; } Switch(n) { Case 1://add to left node if(Bt->left)//left dial hand tree is not empty{printf ("left dial hand tree nodes are not empty!\n"); return 0; }ElseBT->left=node; Break; Case 2://Add to right node if(Bt->right)//Right Sub-tree is not empty{printf ("right subtree node is not empty!\n"); return 0; }ElseBT->right=node; Break; default: printf ("parameter Error!\n"); return 0; } return 1;} Chainbintree*bintreeleft (Chainbintree *BT)//return to the left Dial hand node.{ if(BT)returnBt->Left ; Else returnNULL;} Chainbintree*bintreeright (Chainbintree *BT)//returns the right child node.{ if(BT)returnBt->Right ; Else returnNULL;}intBintreeisempty (Chainbintree *BT)//checks if the two fork tree is empty, returns 1 if empty, or returns 0{ if(BT)return 0; Else return 1;} intBintreedepth (Chainbintree *BT)//finding the depth of a binary tree{ intDep1,dep2; if(bt==NULL)return 0;//for empty trees, the depth is 0 Else{dep1= Bintreedepth (Bt->left);//left dial hand tree depth (recursive invocation)DEP2 = Bintreedepth (bt->right);//Right subtree depth (recursive invocation) if(dep1>Dep2)returnDEP1 +1; Else returnDEP2 +1; }} Chainbintree*bintreefind (Chainbintree *bt,data DATA)//finding a node with a value of data in a binary tree{Chainbintree*p; if(bt==NULL)returnNULL; Else { if(bt->data==data)returnBT; Else{//Recursive lookup to left and right subtrees, respectively if(P=bintreefind (bt->left,data)) returnp; Else if(P=bintreefind (bt->Right , data)) returnp; Else returnNULL; } } } voidBintreeclear (Chainbintree *BT)//Empty the binary tree and turn it into an empty tree{ if(BT) {bintreeclear (BT->left);//Empty left subtreeBintreeclear (Bt->right);//empty Right sub-tree Free(BT);//frees the current node to occupy memory.bt=NULL; } return; }
Traversal of a binary tree:
First Order Traversal (DLR): called the first root sequence traversal, that is, the first access to the root node, and then the first order to traverse the left subtree, and finally by the first order to traverse the right sub-tree.
Mid-sequence Traversal (LDR): called the middle root sequence traversal, that is, by first traversing the left subtree in the middle order, then accessing the root node, and then traversing the right subtree by the middle sequence.
Post-order Traversal (LRD): Called after the root of the number of traversal, that is, the first step through the left subtree, and then follow the order to traverse the right subtree, the last access to the root node.
Traverse by layer: traverse the layer of the two-fork tree, and the result of the traversal can be more intuitively obtained.
voidBINTREE_DLR (Chainbintree *BT,void(*oper) (Chainbintree *p))//First Order Traversal{ if(BT)//tree is not empty, perform the following actions{oper (BT);//processing data for a nodeBINTREE_DLR (bt->left,oper); BINTREE_DLR (BT-right,oper); } return; } voidBintree_ldr (Chainbintree *BT,void(*oper) (Chainbintree *p))//Middle Sequence Traversal{ if(BT)//tree is not empty, perform the following actions{bintree_ldr (BT->left,oper);//Middle sequence traversal left subtreeOper (BT);//Processing node DataBintree_ldr (Bt->right,oper);//the middle sequence traverses the right sub-tree/ } return; } voidBINTREE_LRD (Chainbintree *BT,void(*oper) (Chainbintree *p))//Post-post traversal{ if(BT) {bintree_lrd (BT->left,oper);//To traverse the left subtreeBINTREE_LRD (Bt->right,oper);//To traverse the right sub-treeOper (BT);//Processing node Data } return; }voidOper (Chainbintree *p)//manipulating binary tree node data{printf ("%c", P->data);//Output Data return;}voidBintree_level (Chainbintree *BT,void(*oper) (Chainbintree *p))//Traverse by Layer{Chainbintree*p; Chainbintree*q[queue_maxsize];//define a sequential stack intHead=0, tail=0;//team first, tail serial number if(BT)//if the team first pointer is not empty{Tail= (tail+1)%queue_maxsize;//Calculate loop Queue tail numberQ[tail] = BT;//put the two-fork-root pointer in the team } while(Head!=tail)//queue is not empty, loop{Head= (head+1)%queue_maxsize;//calculate the queue first sequence number for a loopP=q[head];//get the first element of the teamOper (p);//handling Team first elements if(P->left!=null)//If there is a left subtree in the node, the left sub-tree pointer enters the queue .{Tail= (tail+1)%queue_maxsize;//Calculate the queue tail number for the loop queuesq[tail]=p->left;//put the left subtree pointer in the team } if(P->right!=null)//If there is a right child at the junction, the right child points the pointer into the team .{Tail= (tail+1)%queue_maxsize;//Calculate the queue tail number for the loop queuesq[tail]=p->right;//put the right subtree pointer in the team } } return; }
Complex data structure (i) tree