Data Structure --- Binary Tree C Implementation Analysis
If we have learned the data structure, we all know the tree. What is the tree?
A tree contains n (n> 0) knots. (1) Each element is called a node. (2) A specific node is called a root node or a root node ). (3) other data elements except the root node are divided into m (m ≥ 0) sets that do not conflict with each other T1, T2 ,...... Tm-1, where each collection of Ti (1 <= I <= m) itself is also a tree, called the original tree (subtree ). The tree can also be defined as follows: the tree consists of the root node and several sub-trees. A tree consists of a set and a relationship defined on the set. The elements in the set are called Tree nodes, and the defined relationship is called parent-child relationship. The parent-child relationship establishes a hierarchy between the nodes in the tree. In this hierarchy, a node has a special position. This node is called the root node of the tree or the root node of the tree. We can give a recursive definition of the tree as follows: a single node is a tree, and the root is the node itself. Let T1, T2,..., Tk be the tree, and their root nodes are n1, n2,..., nk, respectively. Using a new node n as the father of n1, n2,... and nk, a new tree is obtained. node n is the root of the new tree. We call n1, n2,... and nk A group of sibling nodes. They are all subnodes of node n. We also call T1, T2,..., Tk as the subtree of node n. Empty sets are also called empty trees. No node exists in the empty tree. Common types of trees are: Full Binary Tree, full Binary Tree, binary tree, red and black tree, unordered tree, And Harman tree. Today, we mainly want to learn about Binary Trees,
1. Each node can have a tree structure of up to two subnodes
2. the Start Node is called the root node. Besides the root node, each node has only one parent node.
3. No subnode is called a leaf node. Each node can have two subnodes except a leaf node.
4. In addition to root nodes and leaf nodes, the remaining nodes are called branch nodes. The branches have parent nodes and subnodes.
5. Each layer node of the binary tree reaches the maximum value. Besides the leaf node, each node has two subnodes, called the full binary tree.
6. Except for the last layer, the number of nodes on each layer reaches the maximum value, and the nodes on the last layer are continuously concentrated on the left, called the full binary tree.
The binary tree processing adopts the recursive method:
Processing (Binary Tree)
{
If (Binary Tree is empty) direct processing;
Else
{
Process the root node;
Process the left subtree; => Recursion
Process the right subtree; => Recursion
}
}
Binary Tree Storage Structure
(1) sequential Storage Structure
Store each node from top to bottom, from left to right
(2) chain Storage Structure
In addition to storing data elements, each node also requires two pointers.
For example:
Typedef struct Node {int data; // the data content struct Node * left; // points to the left subtree Node * right; // points to the right subtree} Node;
Traversal Mode
(1) sequential traversal => right subtree of the Left subtree of the root
(2) central order traversal => left subtree root right subtree
(3) Post-order traversal => left subtree right subtree Root
Ordered Binary Tree
Left subtree node <= root node <= right subtree Node
Mainly searching and searching for Data
Next, let's take a look at the implementation of various Binary Tree operations:
// Perform operations on the ordered binary tree # include
# Include
// Define the Node data type typedef struct Node {int data; // store the data content struct Node * left; // the address of the left subtree struct Node * right; // address of the right subtree} Node; // defines the data type of the ordered binary tree, typedef struct {Node * root; // records the address of the root Node, int cnt; // record the number of nodes} Tree; // implement the void insert_data (Tree * pt, int data) operation to insert a new node into the ordered binary Tree ); // insert the recursion function void insert (Node ** pRoot, Node * pn) of the new Node; // use the Middle-order traversal method to traverse void travel_data (Tree * pt ); // The Recursive Function void travel (Node * pRoot) that traverses; // implement the creation of Node * create_node (int data); // implement the clearing tree All nodes in void clear_data (Tree * pt); // implement the clear recursive function void clear (Node ** pRoot ); // find a specified Node ** find_data (Tree * pt, int data); // find the recursive function Node ** find (Node ** pRoot, int data); // Delete the specified node void del_data (Tree * pt, int data); // modify the void modify (Tree * pt, int data, int new_data); // determines whether the binary Tree is null int empty (Tree * pt); // determines whether the binary Tree is full int full (Tree * pt ); // calculate the number of nodes in the binary Tree int size (Tree * pt); // obtain the element value of the root node int get_root (Tree * pt); int main (void) {// Create an Ordered Binary Tree and initialize the tree. root = NULL; tree. cnt = 0; // Insert a new node and traverse insert_data (& tree, 50); travel_data (& tree); // 50insert_data (& tree, 70 ); travel_data (& tree); // 50 70insert_data (& tree, 20); travel_data (& tree); // 20 50 70insert_data (& tree, 60 ); travel_data (& tree); // 20 50 60 70 printf ("------------------ \ n"); // clear_data (& tree); travel_data (& tree ); // 20 50 60 70del_data (& tree, 50); travel_data (& tree); // 20 60 70 Del_data (& tree, 30); // travel_data (& tree) failed to be deleted; // 20 60 70del_data (& tree, 20); travel_data (& tree ); // 60 70 printf ("-------------------- \ n"); modify (& tree, 10, 20); // insert 20travel_data (& tree ); // 20 60 70 printf ("the root node element in the binary tree is % d \ n", get_root (& tree )); // 70 printf ("the number of nodes in the binary tree is % d \ n", size (& tree); // 3 printf ("% s \ n ", empty (& tree )? "Binary tree is empty": "binary tree is not empty"); printf ("% s \ n", full (& tree )? "The binary tree is full": "The binary tree is not full"); return 0 ;}// modify the operation of the specified Element // when the old element does not exist, insert a new element directly to void modify (Tree * pt, int data, int new_data) {// 1. delete the old element del_data (pt, data); // 2. insert new element insert_data (pt, new_data);} // determine whether the binary Tree is NULL int empty (Tree * pt) {return NULL = pt-> root ;} // determine whether the binary Tree is full int full (Tree * pt) {return 0;} // calculate the number of nodes in the binary Tree int size (Tree * pt) {return pt-> cnt;} // obtain the element value of the root node int get_root (Tree * pt) {if (empty (pt) {return-1; // indicates a failure (later)} return pt-> root-> data;} // Delete the specified node void del_data (Tree * pt, int data) {// 1. find the Node Address of the target element ** pp = find_data (pt, data); // 2. to check whether the search fails, you do not need to delete if (NULL = * pp) {printf ("the target element does not exist, delete failed \ n"); return;} // 3. merge left and right subtree and insert left subtree into right subtree if (* pp)-> left! = NULL) {// when the left subtree is not empty, insert (& (* pp)-> right, (* pp) to the right subtree) -> left);} // 4. find the Node Address of the pointer record to be deleted Node * q = * pp; // 5. point the pointer pointing to the node to be deleted to the merged right subtree * pp = (* pp)-> right; // 6. delete the node where the target element is located. free (q); q = NULL; // 7. the number of nodes is reduced by 1pt-> cnt --;} // The Recursive Function Node ** find (Node ** pRoot, int data) {// 1. determine whether the binary tree is NULL. if (NULL = * pRoot) {return pRoot; // & pt-> root;} // 2. compare the size of the root and target elements. if they are equal, return if (data = (* pRoot)-> data) {return pRoot; // & pt-> root;} // 3. if the target element is smaller than the root element Node element value. The left subtree searches for else if (data <(* pRoot)-> data) {return find (& (* pRoot)-> left, data );} // 4. if the target element is greater than the root node element, go to the right subtree to find else {return find (& (* pRoot)-> right, data );}} // find a specified Node // return the Node ** find_data (Tree * pt, int data) pointing to the Node where the target element is located) {// call the recursive function to find return find (& pt-> root, data);} // implement the clear recursive function void clear (Node ** pRoot) {// determine whether the binary tree is null if (* pRoot! = NULL) {// 1. clear the left subtree clear (& (* pRoot)-> left); // 2. clear right subtree clear (& (* pRoot)-> right); // 3. clear the root node free (* pRoot); * pRoot = NULL ;}// clear all nodes in the Tree void clear_data (Tree * pt) {// call the recursive function to clear (& pt-> root); // The number of nodes in the binary tree is cleared pt-> cnt = 0 ;} // create a new Node * create_node (int data) {Node * pn = (Node *) malloc (sizeof (Node); pn-> data = data; pn-> left = NULL; pn-> right = NULL; return pn;} // recursive function void travel (Node * pRoot) of Traversal) {// if (pRoot! = NULL) {// 1. traverse the left subtree travel (pRoot-> left); // 2. traverse the root node printf ("% d", pRoot-> data); // 3. traverse the right subtree travel (pRoot-> right) ;}// traverse void travel_data (Tree * pt) in the middle order) {// call the recursive function to traverse travel (pt-> root); // print the line feed printf ("\ n ");} // insert the recursion function void insert (Node ** pRoot, Node * pn) of the new Node {// 1. determines whether the binary tree is NULL. if it is NULL, let the root node pointer direct to the new node if (NULL = * pRoot) {* pRoot = pn; return;} // 2. if the binary tree is not empty, compare the size of the root node and the new node // 2.1 if the root node is greater than the new node, insert the left subtree if (* pRoot)-> data> pn-> data) {insert (& (* pRoot)-> left, pn) ;}// 2.2 If the root node is less than or equal to the new node, insert the right subtree else {insert (& (* pRoot) -> right, pn) ;}/// implement the void insert_data (Tree * pt, int data) operation to insert a new node into the ordered binary Tree {// 1. create a new Node and initialize create_node // Node * pn = (Node *) malloc (sizeof (Node); // pn-> data = data; // pn-> left = NULL; // pn-> right = NULL; // 2. insert a new node to a binary tree and call the recursive function insert (& pt-> root, create_node (data); // 3. the number of nodes in the binary tree plus 1pt-> cnt ++ ;}
Running result: