Tree implementation and operations (implemented in C)
First, let's briefly describe some basic concepts.
A tree is a non-linear data structure.
1. A tree is a finite set of n (n> = 0) nodes.
If n = 0, it is called an empty tree.
If n> 0, then:
There is a specific node called the root node. It only has direct successor, but there is no direct precursor.
Except for the root, the nodes are divided into m (m> = 0) finite sets of non-Intersecting, T0, T1, T2... Tn-1, each collection is a tree, and it is called the Child tree of the root
2. concepts in the tree:
The node of the tree includes data and several branches pointing to the subtree.
The subtree owned by a node is called the degree of the node.
A node with a degree of 0 is called a leaf node.
A node with a degree of less than 0 is called a branch node.
The degree of the tree is defined as the maximum degree among all nodes.
3. Relationship between nodes in the tree
(1) The child of a node directly becomes the child of the node
(2) The node is called the child's parent.
(3) Children of node ...... The child of the node
(4) the corresponding node is called the descendant's ancestor.
(5) children of the same parent are called brothers.
4. Tree depth or height
(1) node hierarchy
(2) The root layer is 1st layers.
(3) The root child is Layer 3
(4 )......
(5) The maximum hierarchy of nodes in the tree is called the depth or height of the tree.
5. If the Subtrees at the knots in the fruit tree are ordered from left to right, And the Subtrees cannot change their positions, the Subtrees are called ordered trees; otherwise, they are unordered trees.
6. A forest is a collection of n (n> = 0) trees that do not overlap with each other.
7. Tree-related operations
Tree operations
Common Tree operations
-> Create a tree
-> Destroy tree
-> Clear the tree
-> Insert Node
-> Delete a node
-> Get Node
-> Get the root node
-> Get the number of knots in the tree
-> Retrieve the tree height
-> Get the Degree of the tree
The tree represents a special data type in the program.
Tree operations are represented as a group of functions in the program.
Tree:
Tree * Tree_Create ();
VoidTree_Destroy (Tree * tree );
VoidTree_Clear (Tree * tree );
IntTree_Insert (Tree * tree, TreeNode * node, int pos );
TreeNode * Tree_Delete (Tree * tree, int pos );
TreeNode * Tree_Get (Tree * tree, int pos );
TreeNode * Tree_Root (Tree * tree );
IntTree_Height (Tree * tree );
IntTree_Count (Tree * tree );
IntTree_Degree (Tree * tree );
Let's talk about the basic storage structure of the tree here. Assuming that we have a tree, how do we define its storage structure?
First, we stipulate that each tree node has three attributes (1) representing its father's pointer (2) representing data in the node (3) representing the child's linked list, why is it a linked list? A single node may have one or more children, so it is most appropriate to use a linked list.
Second, the relationship between each tree. We can imitate the idea of first-order traversal in a binary tree to traverse the tree. We know that the traversal result must be a sequence, at this time, we can think of this sequence as a chain table structure, so that later Tree operations can be transplanted to the chain table.
Finally, the acquisition and calculation of the depth, degree, deletion, and root node of the tree are all performed on the node indicating the tree. As there are two linked lists in the entire tree, you must delete and insert them to the two linked lists each time you delete them. (A node must exist in both the parent's child linked list and the whole tree linked list.)
Here we use the linked list knowledge. If you are not familiar with the linked list, you can refer to the implementation and operation of the linked list (implemented in C).Detailed code is provided here.
Source code:
#ifndef _GTREE_H_#define _GTREE_H_typedef void GTree;typedef void GTreeData;typedef void (GTree_Printf)(GTreeData*);GTree* GTree_Create();void GTree_Destroy(GTree* tree);void GTree_Clear(GTree* tree);int GTree_Insert(GTree* tree, GTreeData* data, int pPos);GTreeData* GTree_Delete(GTree* tree, int pos);GTreeData* GTree_Get(GTree* tree, int pos);GTreeData* GTree_Root(GTree* tree);int GTree_Height(GTree* tree);int GTree_Count(GTree* tree);int GTree_Degree(GTree* tree);void GTree_Display(GTree* tree, GTree_Printf* pFunc, int gap, char div);#endif
CPP implementation:
# Include "stdafx. h" # include
# Include "GTree. h "# include" LinkList. h "// Tree node typedef struct _ tag_GTreeNode GTreeNode; struct _ tag_GTreeNode {GTreeData * data; GTreeNode * parent; LinkList * child ;}; // tree typedef struct _ tag_TLNode TLNode; struct _ tag_TLNode {LinkListNode header; GTreeNode * node;}; // print tree static void recursive_display (GTreeNode * node, GTree_Printf * pFunc, int format, int gap, char div) {int I = 0; if (node! = NULL) & (pFunc! = NULL) {for (I = 0; I
Data); printf ("\ n"); for (I = 0; I
Child); I ++) {TLNode * trNode = (TLNode *) LinkList_Get (node-> child, I); recursive_display (trNode-> node, pFunc, format + gap, gap, div) ;}} static void recursive_delete (LinkList * list, GTreeNode * node) {if (list! = NULL) & (node! = NULL) {GTreeNode * parent = node-> parent; int index =-1; int I = 0; // Delete the node from the linked list indicating the tree (I = 0; I
Node = node) {LinkList_Delete (list, I); free (trNode); index = I; break ;}// if index> 0, it indicates that he has a father, if (index> = 0) {if (parent! = NULL) {// delete him from his father's child linked list for (I = 0; I
Child); I ++) {TLNode * trNode = (TLNode *) LinkList_Get (parent-> child, I); if (trNode-> node = node) {LinkList_Delete (parent-> child, I); free (trNode); break ;}}// if he has a son, kill all of his sons while (LinkList_Length (node-> child)> 0) {TLNode * trNode = (TLNode *) LinkList_Get (node-> child, 0 ); recursive_delete (list, trNode-> node);} LinkList_Destroy (node-> child); free (node) ;}} static int recursive_height (GTr EeNode * node) {int ret = 0; if (node! = NULL) {int subHeight = 0; int I = 0; for (I = 0; I
Child); I ++) {TLNode * trNode = (TLNode *) LinkList_Get (node-> child, I); subHeight = recursive_height (trNode-> node ); if (ret <subHeight) {ret = subHeight;} ret = ret + 1;} return ret;} static int recursive_degree (GTreeNode * node) {int ret =-1; if (node! = NULL) {int subDegree = 0; int I = 0; ret = LinkList_Length (node-> child); for (I = 0; I
Child); I ++) {TLNode * trNode = (TLNode *) LinkList_Get (node-> child, I); subDegree = recursive_degree (trNode-> node ); if (ret <subDegree) {ret = subDegree; }}return ret;} GTree * GTree_Create () {return LinkList_Create ();} void GTree_Destroy (GTree * tree) {GTree_Clear (tree); LinkList_Destroy (tree);} void GTree_Clear (GTree * tree) {GTree_Delete (tree, 0);} int GTree_Insert (GTree * tree, GTreeData * data, I Nt pPos) {LinkList * list = (LinkList *) tree; // It is passed into the inserted tree, indicating that the essence of the tree is the linked list // validity judgment int ret = (list! = NULL) & (data! = NULL) & (pPos <LinkList_Length (list); // The inserted node must be in the tree. // Therefore, pPos <LinkList_Length (list) if (ret) {TLNode * trNode = (TLNode *) malloc (sizeof (TLNode); // create a node to record the node TLNode * cldNode = (TLNode *) in the linked list of the stored tree *) malloc (sizeof (TLNode); // child (a linked list) TLNode * pNode = (TLNode *) LinkList_Get (list, pPos ); // obtain the parent GTreeNode * cNode = (GTreeNode *) malloc (sizeof (GTreeNode) from the linked list that represents the tree; // The Node to be inserted, used to receive incoming data ret = (t RNode! = NULL) & (cldNode! = NULL) & (cNode! = NULL); // The node in the tree cannot be blank. if (ret) {cNode-> data = data; // Save the data cNode-> parent = NULL; // It is still unclear who his parents are. cNode-> child = LinkList_Create (); // the child of the node to be inserted is a linked table trNode-> node = cNode; // assign the value of the node to be inserted to the linked list cldNode-> node = cNode; // assign the value of the node to be inserted to the Child linked list LinkList_Insert (list, (LinkListNode *) in the tree node *) trNode, LinkList_Length (list); // insert if (pNode! = NULL) // If the node to be inserted has a parent node, insert the node {cNode-> parent = pNode-> node to the child node linked list of the parent node; // identification process // formally join the big family LinkList_Insert (pNode-> node-> child, (LinkListNode *) cldNode, LinkList_Length (pNode-> node-> child ));}} else {free (trNode); free (cldNode); free (cNode) ;}} return ret;} // Delete the GTreeData node * GTree_Delete (GTree * tree, int pos) {TLNode * trNode = (TLNode *) LinkList_Get (tree, pos); GTreeData * ret = NULL; if (trNode! = NULL) {ret = trNode-> node-> data; recursive_delete (tree, trNode-> node);} return ret ;} // obtain the node GTreeData * GTree_Get (GTree * tree, int pos) {TLNode * trNode = (TLNode *) LinkList_Get (tree, pos); GTreeData * ret = NULL; if (trNode! = NULL) {ret = trNode-> node-> data;} return ret;} // obtain the root node GTreeData * GTree_Root (GTree * tree) {return GTree_Get (tree, 0);} // calculate the height of the tree int GTree_Height (GTree * tree) {TLNode * trNode = (TLNode *) LinkList_Get (tree, 0); int ret = 0; if (trNode! = NULL) {ret = recursive_height (trNode-> node);} return ret;} // calculate the number of nodes in the tree int GTree_Count (GTree * tree) {return LinkList_Length (tree);} // calculates the degree of the tree. int GTree_Degree (GTree * tree) {TLNode * trNode = (TLNode *) LinkList_Get (tree, 0 ); int ret =-1; if (trNode! = NULL) {ret = recursive_degree (trNode-> node);} return ret;} void GTree_Display (GTree * tree, GTree_Printf * pFunc, int gap, char div) {TLNode * trNode = (TLNode *) LinkList_Get (tree, 0); if (trNode! = NULL) & (pFunc! = NULL) {recursive_display (trNode-> node, pFunc, 0, gap, div );}}
Main function operation section:
// Tree. cpp: defines the entry point of the console application. // # Include "stdafx. h" # include "GTree. h" # include
Void printf_data (GTreeData * data) {printf ("% c", (int) data);} int _ tmain (int argc, _ TCHAR * argv []) {GTree * tree = GTree_Create (); int I = 0; GTree_Insert (tree, (GTreeData *) 'A',-1); GTree_Insert (tree, (GTreeData *) 'B', 0); GTree_Insert (tree, (GTreeData *) 'C', 0); GTree_Insert (tree, (GTreeData *) 'D ', 0 ); GTree_Insert (tree, (GTreeData *) 'E', 1); GTree_Insert (tree, (GTreeData *) 'F', 1); GTree_Insert (tree, (GTreeData *) 'H', 3); GTree_Insert (tree, (GTreeData *) 'I', 3); GTree_Insert (tree, (GTreeData *) 'J', 3 ); printf ("Tree Height: % d \ n", GTree_Height (tree); printf ("Tree Degree: % d \ n", GTree_Degree (tree )); printf ("Full Tree: \ n"); GTree_Display (tree, printf_data, 2, ''); printf (" Get Tree Data: \ n "); for (I = 0; I
Running result:
Tree Height: 3 Tree Degree: 3 Full Tree: a B e f c d h I JGet Tree Data: ABCDEFHIJGet Root Data: AAfter Deleting D: A--B----E----F -- CAfter Clearing Tree: press any key to continue...
In case of any errors, please do not hesitate to point out.