<< Chapter < Page | Chapter >> Page > |
def search_binary_tree(node, key):
if node is None:
return None # key not found
if key<node.key:
return search_binary_tree(node.left, key)
elif key>node.key:
return search_binary_tree(node.right, key)
else: # key is equal to node key
return node.value # found key
This operation requires O (log n) time in the average case, but needs O (n) time in the worst-case, when the unbalanced tree resembles a linked list.
(From Wikipedia, the free encyclopedia)
Insertion begins as a search would begin; if the root is not equal to the value, we search the left or right subtrees as before. Eventually, we will reach an external node and add the value as its right or left child, depending on the node's value. In other words, we examine the root and recursively insert the new node to the left subtree if the new value is less than the root, or the right subtree if the new value is greater than or equal to the root.
Here's how a typical binary search tree insertion might be performed in C++ :
/* Inserts the node pointed to by "newNode" into the subtree rooted at "treeNode" */
void InsertNode(struct node *&treeNode, struct node *newNode)
{
if (treeNode == NULL)
treeNode = newNode;
else if (newNode->value<treeNode->value)
InsertNode(treeNode->left, newNode);
else
InsertNode(treeNode->right, newNode);
}
The above "destructive" procedural variant modifies the tree in place. It uses only constant space, but the previous version of the tree is lost. Alternatively, as in the following Python example, we can reconstruct all ancestors of the inserted node; any reference to the original tree root remains valid, making the tree a persistent data structure :
def binary_tree_insert(node, key, value):
if node is None:
return TreeNode(None, key, value, None)
if key == node.key:
return TreeNode(node.left, key, value, node.right)
if key<node.key:
return TreeNode(binary_tree_insert(node.left, key, value), node.key, node.value, node.right)
else:
return TreeNode(node.left, node.key, node.value, binary_tree_insert(node.right, key, value))
The part that is rebuilt uses Θ(log n) space in the average case and Ω(n) in the worst case (see big-O notation ).
In either version, this operation requires time proportional to the height of the tree in the worst case, which is O (log n) time in the average case over all trees, but Ω(n2) time in the worst case.
Another way to explain insertion is that in order to insert a new node in the tree, its value is first compared with the value of the root. If its value is less than the root's, it is then compared with the value of the root's left child. If its value is greater, it is compared with the root's right child. This process continues, until the new node is compared with a leaf node, and then it is added as this node's right or left child, depending on its value.
There are other ways of inserting nodes into a binary tree, but this is the only way of inserting nodes at the leaves and at the same time preserving the BST structure.
(From Wikipedia, the free encyclopedia)
Notification Switch
Would you like to follow the 'Data structures and algorithms' conversation and receive update notifications?