Complete Binary Trees
A Complete Binary Tree is a binary tree in which all the levels of the tree are fully filled except possibly for the last level. The last level is filled from left to right, meaning all the nodes at the last level are as left as possible. This tree structure is widely used in implementing heap data structures and binary search trees.
A Complete Binary Tree is defined as a binary tree in which:
A complete binary tree is very useful in heap data structures (like binary heaps) due to its level-wise compact structure.
Here is an example of a complete binary tree:
1
/ \
2 3
/ \ /
4 5 6
In this tree:
Perfect Binary Tree:
Complete Binary Tree:
Insertion in a complete binary tree follows a level-order approach. The new node is added at the leftmost available position on the last level, which ensures that the tree maintains its "complete" structure.
Traversing a binary tree is the process of visiting all its nodes. The common types of tree traversal are:
Deletion in a complete binary tree typically removes the deepest node (the rightmost node) to maintain the completeness of the tree. In some cases, when deleting the root, the tree might be restructured, and the deepest node will replace the root, followed by a heapification process.
Below is a Python implementation of a Complete Binary Tree. It supports insertion, level-order traversal, and both preorder and inorder traversal.
class Node:
def __init__(self, key):
self.left = None
self.right = None
self.value = key
class CompleteBinaryTree:
def __init__(self):
self.root = None
self.size = 0 # Keeps track of the number of nodes in the tree
# Level order insertion for a complete binary tree
def insert(self, root, key):
if root is None:
return Node(key)
queue = [root]
while queue:
temp = queue.pop(0)
# Insert the node in the left child if it's empty
if temp.left is None:
temp.left = Node(key)
return root
else:
queue.append(temp.left)
# Insert the node in the right child if it's empty
if temp.right is None:
temp.right = Node(key)
return root
else:
queue.append(temp.right)
# Level order traversal (breadth-first)
def level_order_traversal(self, root):
if not root:
return
queue = [root]
while queue:
temp = queue.pop(0)
print(temp.value, end=" ")
if temp.left:
queue.append(temp.left)
if temp.right:
queue.append(temp.right)
# Preorder traversal (root-left-right)
def preorder_traversal(self, root):
if root:
print(root.value, end=" ") # Visit root
self.preorder_traversal(root.left) # Visit left subtree
self.preorder_traversal(root.right) # Visit right subtree
# Inorder traversal (left-root-right)
def inorder_traversal(self, root):
if root:
self.inorder_traversal(root.left) # Visit left subtree
print(root.value, end=" ") # Visit root
self.inorder_traversal(root.right) # Visit right subtree
# Example Usage
cbt = CompleteBinaryTree()
cbt.root = cbt.insert(cbt.root, 1)
cbt.insert(cbt.root, 2)
cbt.insert(cbt.root, 3)
cbt.insert(cbt.root, 4)
cbt.insert(cbt.root, 5)
cbt.insert(cbt.root, 6)
print("Level Order Traversal of Complete Binary Tree:")
cbt.level_order_traversal(cbt.root)
print("\nPreorder Traversal of Complete Binary Tree:")
cbt.preorder_traversal(cbt.root)
print("\nInorder Traversal of Complete Binary Tree:")
cbt.inorder_traversal(cbt.root)
Level Order Traversal of Complete Binary Tree:
1 2 3 4 5 6
Preorder Traversal of Complete Binary Tree:
1 2 4 5 3 6
Inorder Traversal of Complete Binary Tree:
4 2 5 1 3 6
Heap Data Structures: Complete binary trees are commonly used in binary heaps to implement priority queues. In heaps, insertion and deletion operations maintain the complete binary tree structure, ensuring efficient retrieval of the maximum or minimum element.
Balanced Search Trees: Although complete binary trees themselves are not always used in search trees, they serve as a foundation for AVL trees and Red-Black trees, which are balanced and maintain optimal search times.
Binary Indexed Trees (Fenwick Trees): Complete binary trees are used in Fenwick trees for efficient range sum queries and updates.
Efficient Memory Storage: The structure of a complete binary tree is ideal for storing data in arrays, as it allows for efficient traversal and indexing.