Binary Tree JavaBinary tree is a tree type non-linear data structure that are mainly used for sorting and searching because they store data in hierarchical form. In this section, we will learn the implementation of binary tree data structure in Java. Also, provides a short description of binary tree data structure. Binary TreeA tree in which each node (parent) has at most two-child nodes (left and right) is called binary tree. The top most node is called the root node. In a binary tree a node contains the data and the pointer (address) of the left and right child node. The height of a binary tree is the number of edges between the tree's root and its furthest (deepest) leaf. If the tree is empty, the height is 0. The height of the node is denoted by h. The height of the above binary tree is 2. We can calculate the number of leaves and node by using the following formula. - Maximum number of leaf nodes is a binary tree: 2h
- Maximum number of nodes is a binary tree: 2h+1-1
Where, h is the height of binary tree. Example of Binary TreeTypes of Binary TreeThere are the following types of binary tree in data structure: - Full/ Strictly Binary Tree
- Complete Binary Tree
- Perfect Binary Tree
- Balance Binary Tree
- Rooted Binary Tree
- Degenerated/ Pathological Binary Tree
- Extended Binary Tree
- Skewed Binary Tree
- Left-skewed Binary Tree
- Right-skewed Binary Tree
- Threaded Binary Tree
- Single Threaded Binary Tree
- Double Threaded Binary Tree
- AVL Tree
- Red Black Tree
- B Tree
- B+ Tree
- Segment Tree
Binary Tree Implementation in JavaThere are many ways to implement binary tree. In this section, we will implement binary tree using LinkedList data structure. Along with it, we will also implement the traversal orders, searching a node and insert a node in a binary tree. Implementation of Binary Tree Using LinkedListAlgorithmDefine Node class that contains three attributes namely: data left and right. Here, left represents the left child of the node and right represents the right child of the node. - When a node is created, data will pass to data attribute of the node and both left and right will be set to null.
- Define another class that has an attribute root.
- Root represents the root node of the tree and initialize it to null.
- insert() will add a new node to the tree:
- It checks whether the root is null, which means the tree is empty. It will add the new node as root.
- Else, it will add root to the queue.
- The variable node represents the current node.
- First, it checks whether a node has a left and right child. If yes, it will add both nodes to queue.
- If the left child is not present, it will add the new node as the left child.
- If the left is present, then it will add the new node as the right child.
- inorder() will display nodes of the tree in inorder fashion.
- It traverses the entire tree then prints out left child followed by root then followed by the right child.
BinarySearchTree.java Output:
Binary tree after insertion
1
Binary tree after insertion
2 1 3
Binary tree after insertion
4 2 5 1 3
Binary tree after insertion
4 2 5 1 6 3 7
Binary Tree OperationsThe following operations can be performed on a binary tree: - Insertion: Adding a new node to the tree.
- Deletion: Removing a node from the tree.
- Traversal:
- In-order Traversal: Visit left subtree, then current node, then right subtree.
- Pre-order Traversal: Visit current node, then left subtree, then right subtree.
- Post-order Traversal: Visit left subtree, then right subtree, then current node.
- Level Order Traversal: Visit nodes level by level, from left to right.
- Search: Finding a specific node with a given value.
Java Program to Insert a Node in Binary TreeBinaryTreeInsert.java Output:
Building tree with root value 25
=================================
Inserted 11 to left of Node 25
Inserted 15 to right of Node 11
Inserted 16 to right of Node 15
Inserted 23 to right of Node 16
Inserted 79 to right of Node 25
Java Program to Delete a Node in JavaAlgorithm- Starting at the root, find the deepest and rightmost node in binary tree and node that we want to delete.
- Replace the deepest rightmost node's data with the node to be deleted.
- Then delete the deepest rightmost node.
Consider the following figure. DeleteNode.java Output:
Inorder traversal before deletion: 7 11 12 10 15 9 8
Inorder traversal after deletion: 8 11 12 10 15 9
Java Program to Search a Node in Binary TreeAlgorithm- Define Node class which has three attributes namely: data left and right. Here, left represents the left child of the node and right represents the right child of the node.
- When a node is created, data will pass to data attribute of the node and both left and right will be set to null.
- Define another class which has two attribute root and flag.
- Root represents the root node of the tree and initializes it to null.
- The Flag will be used to check whether the given node is present in the tree or not. Initially, it will be set to false.
- searchNode() will search for a particular node in the binary tree:
- It checks whether the root is null, which means the tree is empty.
- If the tree is not empty, it will compare temp's data with value. If they are equal, it will set the flag to true and return.
- Traverse left subtree by calling searchNode() recursively and check whether the value is present in left subtree.
- Traverse right subtree by calling searchNode() recursively and check whether the value is present in the right subtree.
SearchBinaryTree.java Output:
Element is present in the binary tree.
Binary Tree TraversalTraversal Order | First Visit | Second Visit | Third Visit |
---|
Inorder | Visit left subtree in inorder | Visit root node | Visit right subtree in inorder | Preorder | Visit root node | Visit left subtree in preorder | Visit right subtree in preorder | Postorder | Visit left subtree in postorder | Visit right subtree in postorder | Visit root node |
Note: Except the above three traversals, there is another traversal order is called boundary traversal.Java Program to Traverse Inorder, Preorder, and Postorder TraversalBinaryTree.java Output:
Inorder traversal of binary tree
12 34 56 67 89 90
Preorder traversal of binary tree
34 12 56 89 67 90
Postorder traversal of binary tree
12 67 90 89 56 34
Besides the above operations, we can also perform the operations such as large node, smallest node, and sum of all nodes. Java Program to Find the Largest Node in Binary TreeLargestNode.java Output:
Largest element in the binary tree: 99
Java Program to Find the Smallest Node in Binary TreeAlgorithm- Define Node class which has three attributes namely: data, left and right. Here, left represents the left child of the node and right represents the right child of the node.
- When a node is created, data will pass to data attribute of node and both left and right will be set to null.
- Define another class which has an attribute root.
- Root represent root node of the tree and initialize it to null.
- smallestElement() will find out the smallest node in binary tree:
- It checks whether root is null, which means tree is empty.
- If tree is not empty, define a variable min that will store temp's data.
- Find out the minimum node in left subtree by calling smallestElement() recursively. Store that value in leftMin. Compare the value of min with leftMin and store the minimum of two to min.
- Find out the minimum node in right subtree by calling smallestElement() recursively. Store that value in rightMin. Compare the value of min with rightMin and store the maximum of two to min.
- At the end, min will hold the smallest node in the binary tree.
SmallestNode.java Output:
Smallest element in the binary tree: 1
Java Program to Find the Maximum Width of a Binary TreeAlgorithm- Define Node class which has three attributes namely: data left and right. Here, left represents the left child of the node and right represents the right child of the node.
- When a node is created, data will pass to data attribute of the node and both left and right will be set to null.
- Define another class which has an attribute root.
- Root represents the root node of the tree and initializes it to null.
- findMaximumWidth() will find out the maximum width of the given binary tree:
- Variable maxWidth will store the maximum number of nodes present in any level.
- The queue is used for traversing binary tree level-wise.
- It checks whether the root is null, which means the tree is empty.
- If not, add the root node to queue. Variable nodesInLevel keeps track of the number of nodes in each level.
- If nodesInLevel > 0, remove the node from the front of the queue and add its left and right child to the queue. For the first iteration, node 1 will be removed and its children nodes 2 and 3 will be added to the queue. In the second iteration, node 2 will be removed, its children 4 and 5 will be added to the queue and so on.
- MaxWidth will store max(maxWidth, nodesInLevel). So, at any given point of time, it will represent the maximum number of nodes.
- This will continue till all the levels of the tree is traversed.
BinaryTree.java Output:
Maximum width of the binary tree: 4
Find Maximum Element of the Binary TreeFinding the maximum element of a Binary Tree involves recursively comparing values in the tree nodes to determine the highest value. It is essential for various algorithms, aiding in efficient search operations and understanding the tree's structure. BinaryTreeMaxElement.java Output:
Maximum element in the binary tree is: 5
Time Complexity: O(n) Space Complexity: O(n) Find Height of the Binary TreeThe height of a tree is a fundamental metric that measures the length of the longest path from the root to any leaf node. It quantifies the depth of the tree structure, reflecting its overall size and complexity BinaryTreeHeight.java Output:
Height of the binary tree is: 3
Time Complexity: O(n) where n is the number of nodes in the tree. Auxiliary Space Complexity: O(h) where h is the height of the tree. Find Deepest Node of the Binary TreeFinding the deepest node of a tree involves identifying the node that is farthest from the root. This node is located at the maximum depth of the tree and has no children. DeepestNodeInBinaryTree.java Output:
Deepest node in the binary tree is: 5
Time Complexity: O(n) Auxiliary Space Complexity: O(w) Left view of the TreeThe left view of a binary tree refers to the nodes that are visible when the tree is viewed from the left-hand side. It includes the first node of each level starting from the root going to the leftmost leaf. LeftViewOfBinaryTree.java Output:
Left view of the binary tree is: [1, 3, 4]
Time Complexity: O(n) (linear, where n is the number of nodes in the binary tree) Auxiliary Space Complexity: O(m), where m is the maximum number of nodes at any level in the binary tree Right View of the Binary TreeThe right view of a binary tree refers to the set of nodes visible when the tree is viewed from the right side. It includes the topmost node at each level, allowing us to see the rightmost nodes of the tree at each level. RightViewOfBinaryTree.java Output:
Right view of the binary tree is: [1, 2, 5]
Time Complexity: O(n), where n is the number of nodes in the binary tree. Auxiliary Space Complexity: O(m), where m is the maximum number of nodes at any level in the binary tree. Top View of the Binary TreeThe top view of a binary tree refers to the nodes visible from the top when the tree is viewed from above. It consists of the nodes that are the first to be encountered in each vertical level, starting from the root. TopViewOfBinaryTree.java Output:
Top view of the binary tree is: [4, 3, 1, 2]
Time Complexity: O(N) Auxiliary Space Complexity: O(N) Bottom View of the TreeThe bottom view of a binary tree refers to the nodes visible from the bottom when the tree is viewed from the bottom up. It displays the lowest nodes of the tree, taking into account their horizontal distance from the root. BottomViewOfBinaryTree.java Output:
Bottom view of the binary tree is: [4, 3, 5, 2]
Time Complexity: O(N) Auxiliary Space Complexity: O(N) The Mirror Image of the TreeThe mirror image of a tree, also known as the mirror tree or the inverted tree, is a binary tree that is formed by swapping the left and right children of each node in the original tree. This transformation results in a tree where the structure is reversed along the vertical axis, with each node's children mirrored. MirrorImageOfBinaryTree.java Output:
Original tree:
4 3 5 1 2
Mirror image of the tree:
2 1 5 3 4
Time Complexity: O(n) Auxiliary Space Complexity: O(h) Serialize a Binary TreeTree serialization involves converting a binary tree into a format that can be stored or transmitted and later reconstructed, while preserving its structure. This process typically uses a traversal method, such as preorder, and includes markers for null nodes. Below is a Java program that implements this approach: SerializeDeserializeBinaryTree.java Output:
Serialized tree: 1 3 4 null null 5 null null 2 null null
Inorder traversal of deserialized tree: 4 3 5 1 2
Time Complexity: O(n) where n is the number of nodes in the binary tree. Auxiliary Space: O(n) where n is the number of nodes in the binary tree. Application of Binary Trees- Search Algorithms: Binary search trees (BSTs) enable efficient search operations. The search for a specific element can be performed in O(log n) time complexity, where n is the number of nodes, making it faster than linear search in unsorted data.
- Sorting Algorithms: Binary trees are the basis for efficient sorting algorithms like binary search tree sort and heap sort. These algorithms benefit from the tree's structure to organize data and perform sorting operations efficiently.
- Database Systems: Binary trees are used in database systems to store and manage data. Each node represents a record, allowing for efficient search operations and handling large datasets. B-trees and their variants are commonly used for indexing in databases.
- File Systems: Binary trees can be used to implement file systems, where each node represents a directory or file. This structure allows for efficient navigation, organization, and searching within the file system.
- Compression Algorithms: Huffman coding, a popular compression algorithm, uses binary trees to assign variable-length codes to characters based on their frequency in the input data. This leads to efficient data compression by reducing the overall size.
- Decision Trees: In machine learning, decision trees are used for classification and regression analysis. Each node represents a decision based on an attribute, and the structure of the tree helps in making predictions by traversing from the root to the leaf nodes.
- Game AI: Binary trees are employed in game AI to represent possible moves in a game. The AI algorithm searches the tree to evaluate and choose the best possible move, improving the decision-making process in games like chess or tic-tac-toe.
Advantages of Binary Tree- Efficient Searching: Binary trees enable efficient searching operations since each node has at most two children, allowing the use of binary search algorithms. This facilitates search operations with a time complexity of O(log n).
- Ordered Traversal: The structure of binary trees supports various traversal methods, such as in-order, pre-order, and post-order traversals. This allows for operations on nodes in a specified sequence, such as printing nodes in sorted order.
- Memory Efficiency: Binary trees are relatively memory-efficient compared to other tree structures because each node requires only two pointers. This makes them suitable for storing large amounts of data in memory while maintaining efficient search operations.
- Fast Insertion and Deletion: Binary trees support insertion and deletion operations with a time complexity of O(log n). This makes them ideal for dynamic data structures used in applications like database systems.
- Ease of Implementation: Binary trees are straightforward to implement and understand, making them a popular choice for a variety of applications.
- Effective Sorting: Binary trees are useful for implementing efficient sorting algorithms, such as heap sort and binary search tree sort.
Disadvantages of Binary Tree- Limited Structure: Binary trees are constrained to two child nodes per node, which may not be suitable for applications that require nodes with more than two children. In such cases, different tree structures might be more appropriate.
- Unbalanced Trees: Unbalanced binary trees, where one subtree is significantly larger than the other, can lead to inefficient search operations. This can happen if the tree is not properly balanced or if data is inserted in a non-random order.
- Space Inefficiency: Binary trees can be space-inefficient compared to other data structures due to the two child pointers required for each node, leading to significant memory overhead for large trees.
- Slow Performance in Worst-Case Scenarios: In the worst-case scenario, a binary tree can become degenerate, resembling a linked list where each node has only one child. In such cases, search operations degrade to O(n) time complexity.
- Complex Balancing Algorithms: Maintaining balanced binary trees often requires complex algorithms, such as those used in AVL trees and red-black trees. These balancing mechanisms can be challenging to implement and add additional overhead, making them less suitable for some applications.
|