Tree, binary tree, binary search tree

Source: Internet
Author: User

Reprint: Vamei Source: Http://www.cnblogs.com/vamei

Characteristics and definition of a tree

A tree is a collection of elements. Let's introduce the tree in a more intuitive way. The following data structure is a tree:

The tree has multiple nodes (node) to store elements. There is a certain relationship between some nodes, which is indicated by the line, and the connection is called Edge (edge). The upper node of the edge is called the parent node, and the lower end is called the child node. The tree is like a root that is constantly forked.

Each node can have more than one child node (children), and the node is the parent of the corresponding child node (parent). For example, 3,5 is a child node of 6, 6 is the parent of 3,5, 1,8,7 is a child of 3, and 3 is the parent of 1,8,7. The tree has a node that has no parent node, called the root node (root), 6. A node that has no child nodes is called a leaf node (leaf), than the 1,8,9,5 node in. You can also see that the tree above has a total of 4 levels, 6 in the first layer, and 9 in the fourth floor. The maximum level of nodes in a tree is called depth. In other words, the depth of the tree (depth) is 4.

If we start looking down from node 3 and ignore the rest. So what we see is a tree with node 3 as the root node:

A triangle represents a tree

Further, if we define an isolated node that is also a tree, the original tree can be represented as a relationship between the root node and the subtree (subtree):

These observations actually give us a strict way to define trees:

1. A tree is a collection of elements.

2. The collection can be empty. There are no elements in the tree, we call the tree empty tree.

3. If the collection is not empty, then the collection has one root node, and 0 or more subtrees. The root node is connected to the root node of its subtree with one edge (edge).

The 3rd above is to define the tree recursively, that is, the tree itself (subtree) is used in the process of defining the tree. Due to the recursive nature of the tree, many tree-related operations can also be implemented conveniently using recursion. We'll see in the back.

(the definition above comes from "Data structures and algorithm analysis in C, by Mark Allen Weiss". I think there is a little bit less strict in the place. If the empty tree belongs to the tree, the 3rd should be "... and 0 and more non-empty-empty trees ... ")

The implementation of the tree

The tree has given a memory implementation of the tree: each node stores elements and multiple pointers to child nodes. However, the number of child nodes is indeterminate. A parent node may have a large number of child nodes, and another parent node may have only one child node, and the tree's additions and deletions node operations will cause the number of child nodes to change further. This uncertainty can lead to a lot of memory-related operations, and easy to create memory waste.

A classic implementation is as follows:

Memory implementation of the tree

Each of the two nodes that have the same parent node is the sibling node (sibling). Implementation, each node contains a pointer to the first child node, and another pointer to its next sibling node. In this way, we can represent each node in a uniform, deterministic structure.

The computer's file system is the structure of the tree, as described in the background knowledge of Linux file management. In UNIX file systems, each file (the folder is also a file) can be viewed as a node. Non-folder files are stored on leaf nodes. The folder has pointers to the parent and child nodes (in Unix, the folder also contains a pointer to itself, which differs from the tree we see above). In Git, there is a similar tree structure to express the entire file system version changes (refer to version Management Kingdoms).

File tree

C Implementation of binary search tree

Binary tree (binary) is a special kind of tree. A binary tree can have up to 2 child nodes per node:

Two-fork Tree

Because the number of sub-nodes of the binary tree is determined, it can be implemented in memory directly by the way. Each node has a left children and a right child node (starboard children). The left Dial hand node is the root node of the Zuozi, and the right child node is the root node of the right subtree.

If we add an extra condition to the binary tree, we can get a special binary tree called the binary search tree. Binary search Tree Requirements: Each node is not smaller than any element of its left subtree, and is no larger than any element of its right sub-tree.

(If we assume that there are no duplicate elements in the tree, the above requirements can be written as follows: Each node is larger than any node in its left subtree and smaller than any node in its right subtree)

Binary search tree, notice the size of the elements in the tree

Binary search tree can easily implement the search algorithm. When searching for element x, we can compare the x and the root node:

1. If x equals the root node, then find x, stop the search (termination condition)

2. If x is a small root node, then search Zuozi

3. If x is greater than the root node, then search the right subtree

The binary search tree requires the most number of operations to be equal to the depth of the tree. The depth of the two-fork search tree for n nodes is at most n, with a minimum of log (n).

The following is a C language implementation of the two-fork search tree, and there are search, insert, delete, to find the largest point of the operation of the bar. There are three pointers in each node, one pointing to the parent node, one pointing to the left dial hand node, and one pointing to the right child node.

(This implementation is for convenience.) Nodes can save only two pointers to the left and right child nodes, and do this. )

Deleting a node is relatively complex. After deleting a node, it is sometimes necessary to make some adjustments to restore the nature of the binary search tree (each node is no smaller than any element of its left subtree, and is no larger than any of its right subtrees).

    • Leaf nodes can be deleted directly.
    • When you delete a non-leaf node, such as Node 8 in, we can delete the largest element in the left subtree (or the largest element in the right tree) and use the deleted node to supplement the vacancy created by element 8. But the element may not be a leaf node, so the vacancy it generates requires additional elements ... Until you finally delete a leaf node. The above procedure can be implemented recursively.

Delete a node

Two-fork search tree after deleting a node

/* by Vamei *//* binary search tree */#include <stdio.h> #include <stdlib.h>typedef struct node *position;typed    EF int elementtp;struct Node {position parent;    elementtp element;    Position Lchild; Position rchild;};/ * pointer = root node of the tree */typedef struct node *tree;void print_sorted_tree (tree);p osition find_min (tree);p OS Ition Find_max (tree);p osition find_value (tree, elementtp);p osition insert_value (tree, elementtp); Elementtp Delete_node (position); static int is_root (position); static int is_leaf (position); static Elementtp Delete_    Leaf (position), static void Insert_node_to_nonempty_tree (tree, position), void main (void) {tree tr;    Position NP;    elementtp element;    tr = NULL;    TR = Insert_value (tr, 18);    TR = Insert_value (tr, 5);     TR = Insert_value (tr, 2);    TR = Insert_value (tr, 8);    TR = Insert_value (tr, 81);    TR = Insert_value (tr, 101);    printf ("original:\n");    Print_sorted_tree (TR);    NP = Find_value (TR, 8); if (NP! = NULL){Delete_node (NP);        printf ("After deletion:\n");    Print_sorted_tree (TR);    }}/* * Print values of the tree in sorted order */void Print_sorted_tree (tree tr) {if (tr = = NULL) return;    Print_sorted_tree (Tr->lchild);    printf ("%d \ n", tr->element); Print_sorted_tree (tr->rchild);}    /* * Search for Minimum value * Traverse lchild */position find_min (TREE tr) {position NP;    NP = TR;    if (NP = = NULL) return null;    while (np->lchild! = NULL) {NP = np->lchild; } return NP;}    /* * Search for maximum value * Traverse rchild */position Find_max (TREE tr) {position NP;    NP = TR;    if (NP = = NULL) return null;    while (np->rchild! = NULL) {NP = np->rchild; } return NP;}     /* * Search for value * */position Find_value (TREE tr, elementtp value) {if (tr = = NULL) return null;    if (tr->element = = value) {return TR; } else if (value < tr->element) {return Find_value (Tr->lchild, ValUE);    } else {return Find_value (tr->rchild, value);    }}/* * Delete node NP */elementtp Delete_node (position NP) {position replace;    elementtp element;    if (Is_leaf (NP)) {return delete_leaf (NP);  } else {/* If a node is not a leaf and then we need to find a replacement */replace = (np->lchild! = NULL)?        Find_max (Np->lchild): Find_min (Np->rchild);        element = np->element;        Np->element = Delete_node (replace);    return element;     }}/* * Insert a value into the tree * return root address of the tree */position Insert_value (tree tr, elementtp value) {    Position NP;    /* Prepare the node */NP = (position) malloc (sizeof (struct node));    Np->element = value;    Np->parent = NULL;    Np->lchild = NULL;     Np->rchild = NULL;    if (tr = = NULL) tr = NP;    else {insert_node_to_nonempty_tree (TR, NP); } return TR;} =============================================/* * NP is ROot? */static int Is_root (position NP) {return (np->parent = = NULL);} /* * NP is leaf? */static int is_leaf (position NP) {return (Np->lchild = = NULL && np->rchild = null);} /* * If an element was a leaf, * then it could was removed with no side effect.    */static elementtp delete_leaf (position np) {elementtp element;    Position parent;    element = np->element;    Parent = np->parent;        if (!is_root (NP)) {if (Parent->lchild = = NP) {parent->lchild = NULL;        } else {parent->rchild = NULL;    }} free (NP); return element;} /* * Insert a node to a non-empty tree * called by insert_value () */static void Insert_node_to_nonempty_tree (tree tr, posi            tion NP) {/* Insert the node */if (np->element <= tr->element) {if (Tr->lchild = = NULL) {            /* Then tr->lchild are the proper place */tr->lchild = NP;            Np->parent = TR;    Return    } else {Insert_node_to_nonempty_tree (tr->lchild, NP);             }} else if (Np->element > Tr->element) {if (Tr->rchild = = NULL) {tr->rchild = NP;            Np->parent = TR;        Return        } else {Insert_node_to_nonempty_tree (tr->rchild, NP); }    }}

Operation Result:

Original:
2
5
8
18
81
101
After deletion:
2
5
18
81
101

The deletion in the above implementations is more complex. There is a simple alternative operation called lazy Delete (lazy deletion). When lazy Delete, we do not really remove the node from the two-fork search tree, but instead mark the node as "deleted." In this way, we can complete the deletion of the element by simply locating the element and marking it. If there is a re-insertion of the same element, we can locate the node and cancel the deletion of the tag.

Lazy Delete Implementation is relatively simple, you can try. The memory space occupied by the tree is not reduced by deleting the node. Lazy nodes actually use memory space in exchange for ease of operation.

Tree, binary tree, binary search tree

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.