Binary Search Tree-Array Implementation

Source: Internet
Author: User

A tree is a relatively complex data structure. It is either empty or has one value and has zero or more children. Each child is a tree, this is a recursive definition. Binary trees are a special form of trees and the most common form of data structures. Binary trees can be divided into many types based on the relationship between left and right children nodes and nodes, here we take the binary search tree as an example. The binary search tree has an additional feature: the value of each node is greater than that of all the nodes in its left subtree, but it is smaller than the value of all nodes in the right subtree. This definition eliminates the possibility that nodes with the same value exist in the tree. Binary Search Tree is an excellent tool for quick data search with key values.

Like analysis stacks and queues, we first analyze the interfaces provided by the binary search tree. The first is data insertion insertbst () and data deletion deletebst (). Since it is an excellent tool for searching data, it is essential to query the serchbst () interface. Unlike the stack and queue, the binary tree has no limit on accessing only one value, therefore, a binary tree has a basic operation traversal. In addition, it is the establishment and destruction of the Binary Search Tree.

The interface is as follows:

 

/* Interface Definition of the Binary Search Tree module * // ** the type of the value defined here is an integer. ** in actual use, you can modify the value as needed */# define tree_type int # define true 1 # define false 0/*** insert () add a new value to the tree. The parameter is the value to be added. ** it must not exist in the tree, ** because the binary search tree does not have the same value function, return true or false */INT insertbst (tree_type value);/*** find () to find a specific value, this value is passed as the first parameter to the function **. The function returns a pointer to this value. If no value is found, the function returns NULL */tree_type * findbst (tree_type value) /*** pre_order_traverse ** executes the forward traversal of the genus. Its parameter is a callback function pointer, ** the function to which it points will process each node called in the tree, and the ** node value will be passed as a parameter to this Functions. */Void pre_order_traverse (void (* callback) (tree_type value )); 

 

Creating a binary tree is actually a process of constantly inserting new values, because this new value must be inserted to a proper position to continue to maintain the feature of the Binary Search Tree. The basic idea of insert is as follows:

If the fruit tree is empty:

Insert the new value as the heel Node

Otherwise:

If the new value is smaller than the value of the current node:

Insert the new value to the left subtree of the current node.

Otherwise:

Insert the new value into the right subtree of the current node

This algorithm is based on the definition of the binary tree for search. You can read this algorithm as a recursion and a tail recursion. Therefore, it is easy to use iteration instead of Recursion to improve program efficiency.

It is difficult to delete a value from the binary search tree. Deleting a node from the center of a number will lead to the disconnection between its subtree and the rest of its genus. We must re-link them, three solutions are available: delete nodes with no children, delete nodes with one child, and delete nodes with two children. The first case is relatively simple. You can simply delete the node without causing the subtree to be disconnected because the node has no subtree, when deleting a node with a child, you can connect the parent node of the node with its child. The last case is difficult because one node has two children, its Parent and Child cannot be linked to its two children. One policy to solve this problem is to delete the largest value of its left subtree and use this value to replace the value of the previously deleted node.

Because of the Order of the binary search tree, it is easier to find a fixed value in the tree. It is agreed that it is a recursive algorithm:

If the fruit tree is empty:

This value does not exist in the tree.

Otherwise:

If the value is equal to the value of the root node:

This value is successfully found.

Otherwise:

If the value is smaller than the root value:

Search left subtree

Otherwise:

Find the right subtree

This is also a tail recursion that can be replaced by iteration to improve the efficiency of the algorithm.

Nodes in the traversal tree have several different orders. The most common ones are pre-order, middle-order, post-order, and hierarchical traversal. All types of traversal start with the following node of the tree or the root node of the Child tree you want to traverse.

Pre-order traversal: simple notes are "Left and Right". First, check the root node and then traverse the left subtree. traversing the left subtree is also a "Left and Right" approach, after the subtree is traversed, the right subtree is traversed in the "Left and Right" way, that is, the traversal is also a recursive method.

In-order traversal: It can be recorded as "Left root and right"; in-order traversal, it can be recorded as "Left root and right root ". For more information about the Traversal method, see the method of forward traversal.

Level traversal: The level traversal starts from the same node and starts from the left to the right of the same layer. A common practice is to use queues for hierarchical traversal. when accessing a given node, the left and right children of the node enter the queue, and then traverse the nodes from the queue in sequence.

 

The next step is to implement the interfaces of the binary search tree, or use static arrays, dynamic arrays, and chained structures like stacks and queues.

The implementation of static arrays is relatively simple. It is easy for the left and right children of a node to calculate and process. The subscript of an array can be used to replace the pointer. Therefore, no extra space is required to store the pointer pointing to the left and right nodes, the calculation formula is as follows:

The parent node of node N is n/2 (note that there is no problem here, because the division of integers removes the fractional part)

Node n's left child node is: 2 * n

The right child node of node N is: 2 * n + 1

Note that this rule is established on the root node as an element with the array subscript of 1, but in fact, the array starts with the following mark 0. If you do not want to ignore the 0th space of the array, you Can slightly modify the formula:

Node n's parent nodes are: (n + 1)/2-1

The left child node of node N is 2 * n + 1.

The right child node of node N is 2 * n + 2.

Since the number of array elements is predetermined, no matter whether the binary tree has only the space allocated, a special value must be used to identify whether the value is used, the value 0 is used as the unused ID of this node.

The specific implementation method is as follows:

 

/* Binary Search Tree implemented using static arrays */# include <stdio. h> # include "tree. H "/* defines the maximum length of the array used to store binary trees */# define tree_size 100/* defines a special value for identifying nodes that are not used */# define blank 0 static tree_type tree [tree_size ]; /*** calculate the subscript of the left child of a node */static int left_child (INT current) {Return Current * 2 + 1 ;} /*** calculate the subscript of the right child of a node */static int right_child (INT current) {Return Current * 2 + 2 ;} /*** Insert new value */INT insert (tree_type value) {int current;/* Ensure that the value is not 0, because 0 is used to identify an unused Node */If (value = blank) {printf ("the inserted value is invalid! /N "); Return false;}/* compare from the root node, use iteration to replace recursion */current = 0; while (tree [current]! = Blank) {If (value <tree [current]) {current = left_child (current);} else {If (value = tree [current]) {printf ("the value to be inserted already exists! /N "); Return false;} else {current = right_child (current );}}} /* Whether the value to be inserted exceeds the array range */If (current> = tree_size) {printf ("the inserted value is out of the array range! /N "); Return false;} tree [current] = value; return true;}/*** find node */tree_type * Find (tree_type value) {int current; /*** first, determine whether the value to be searched is special for identifying unused nodes */If (value! = Blank) {current = 0; while (current <tree_size) & (tree [current]! = Value) {If (value <tree [current]) {current = left_child (current);} else {current = right_child (current) ;}} if (current <tree_size) {return tree + current;} return NULL;}/*** the traversal of a binary tree. Here, the node value is printed to reflect the traversal result */static void print (tree_type value) {printf ("% d/N", value);}/*** do_pre_order_traverse ** execute a layer of forward traversal, that is, the left and right of the root, implement */static void do_pre_order_traverse (INT current, void (* print) (tree_type value) {if (Current <tree_size) & (tree [current]! = Blank) {print (tree [current]); do_pre_order_traverse (left_child (current), print); do_pre_order_traverse (right_child (current), print );}} /*** binary tree traversal */void pre_order_traverse (void) {do_pre_order_traverse (0, print );} /*** deletion of a binary tree node ** should be discussed in three cases */INT delet (tree_type value) {tree_type * del; del = find (value); If (Del! = NULL) {/* if no child node */If (left_child (Del-tree)> tree_size) | (tree [left_child (Del-tree)] = blank) & (right_child (Del-tree)> tree_size) | (tree [right_child (Del-tree)] = blank ))) {tree [del-tree] = blank;}/* If two child nodes exist */else {If (left_child (Del-tree) <tree_size) & (tree [left_child (Del-tree)]! = Blank) & (right_child (Del-tree) <tree_size) & (tree [right_child (Del-tree)]! = Blank )) {/*** find the node with the largest value in the left child of the node to replace the node to be deleted ** here, you can also use the smallest node of the right child to replace the node to be deleted ** here the largest node of the left child is actually the rightmost leaf node of the left child */tree_type * right_max; right_max = del-tree; while (right_max <tree_size) & (tree [(INT) right_max]! = Blank) {right_max = right_child (right_max);}/* the maximum value should be its parent node */right_max = (tree_type *) because it determines whether it is the rightmost node *) (INT) right_max-2)/2);/* use the largest node of the left child to replace the node to be deleted */tree [del-tree] = tree [(INT) right_max]; tree [(INT) right_max] = blank;}/* if there is only one child node */else {If (right_child (Del-tree) <tree_size) & (tree [right_child (Del-tree)]! = Blank) {tree [del-tree] = tree [right_child (Del-tree)]; tree [right_child (Del-tree)] = blank ;} else {tree [del-tree] = tree [left_child (Del-tree)]; tree [left_child (Del-tree)] = blank ;}} return true ;} printf ("the node you want to delete is not found! /N "); Return false ;} 

The Implementation of Dynamic Arrays only involves the process of creating arrays. Other implementations are the same as those of static arrays.

 

 

 

 

 

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.