Professional Documents
Culture Documents
Unit 4 - Binary Tree
Unit 4 - Binary Tree
Tree
data structure
1. Root: The topmost node of a tree is called the root. There is no edge pointing to it, but one or
more than one edge originating from it. Here, A is the root node.
2. Parent: Any node which connects to the child. Node which has an edge pointing to some other
node. Here, C is the parent of H.
3. Child: Any node which is connected to a parent node. Node which has an edge pointing to it from
some other node. Here, H is the child of C.
4. Siblings: Nodes belonging to the same parent are called siblings of each other. Nodes B, C and D
are siblings of each other, since they have the same parent node A.
5. Ancestors: Nodes accessible by following up the edges from a child node upwards are called the
ancestors of that node. Ancestors are also the parents of the parents of …… that node. Here, nodes
A, C and H are the ancestors of node I.
6. Descendants: Nodes accessible by following up the edges from a parent node downwards are
called the descendants of that node. Descendants are also the child of the child of …… that node.
Here, nodes H and I are the descendants of node C.
• Leaf/ External Node: Nodes which have no edge originating from it, and have no
child attached to it. These nodes cannot be a parent. Here, nodes E, F, G and I are
leaf nodes.
• Internal node: Nodes with at least one child. Here, nodes B, D and C are internal
nodes.
• Depth: Depth of a node is the number of edges from root to that node. Here, the
depth of nodes A, C, H and I are 0, 1, 2 and 3 respectively.
• Height: Height of a node is the number of edges from that node to the deepest
leaf. Here, the height of node A is 3, since the deepest leaf from this node is node
I. And similarly, height of node C is 2.
1.A tree with n nodes has n-1 Why n-1?
• Because in a tree, there is one and only edge corresponding to all the nodes except
the root node. The root node has no parent, hence no edge pointing to it.
Therefore, a total of n-1 edges.
2.The degree of a node in a tree is the number of children of a node.
3.The degree of a tree is the highest degree of a node among all the nodes
present in the tree.
Binary Tree:
• Binary Tree: A binary tree is a special type of tree where each node has a degree
equal to or less than two which means each node should have at most two
children.
Example 1 has nodes A, B, C, D, E with degrees {2, 0, 1, 1, 0} respectively which satisfies the
conditions for a binary tree. Similarly, example 2 has nodes A and B, having degrees 1 each,
hence a binary tree.
What is a binary tree?
• Property 1: each node can have up to two
successor nodes.
What is a binary tree? (cont.)
• Property 2: a unique path exists from the root to
every other node
• Full or Strict Binary trees: Binary trees as we said earlier have a degree of 2 or
less than 2. But a strict binary tree is a binary tree having all of its nodes with a degree of
2 or 0. That is each of its nodes either have 2 children or is a leaf node.
this binary tree is not a strict or full binary tree because the colored node has a
degree of just 1.
• Perfect Binary Tree: A perfect binary tree has all its internal nodes with degree strictly
2 and has all its leaf nodes on the same level. A perfect binary tree as the name suggests
appears exactly perfect.
This binary tree is not a perfect binary tree because the colored node is
an internal node and has a degree of just 1, although each leaf node is on
the same level.
• Complete Binary Tree: A complete binary tree has all its levels completely filled
except possibly the last level. And if the last level is not completely filled then the last
level’s keys must be all left-aligned.
• Degenerate tree: The easiest of all, degenerate trees are binary trees where
every parent node has just one child and that can be either to its left or right.
• Skewed trees: Skewed trees are binary trees where every parent node has just a single
child and that child should be strict to the left or to the right for all the parents. Slewed
trees having all the child nodes aligned to the left are called left-skewed trees, and skewed
trees having all the child nodes aligned to the right are called right-skewed trees.
What is the max nodes
at some level l?
20
21
22
23
What is the total nodes N
of a full tree with height h?
0 1 h 1 h
N 2 2 ... 2 2 1
l=0 l=1 l=h-1
h
2 1 N
h
2 N 1
h log( N 1) O (log N )
Array representation of Binary trees:
• Arrays are linear data structures and for arrays to function, their size must be specified
before elements are inserted into them. And this counts as the biggest demerit of
representing binary trees using arrays. Suppose you declare an array of size 100, and after
storing 100 nodes in it, you cannot even insert a single element further, regardless of all
the spaces left in the memory.
Linked Representation of Binary Trees:
• This method of representing binary trees using linked nodes is considered the most
efficient method of representation. For this, we use doubly-linked lists. Using links makes
the understanding of a binary tree very easy. It actually makes us visualize the tree even.
Suppose we have a binary tree of 3 levels.
a doubly linked list helped us traversing both to the left and the right. And using
that we would create a similar node here, pointing both to the left and the right
child node.
• this representation resembles a real tree node, unlike the array representation where all the nodes
succumbed to a 2D structure. And now we can very easily transform the whole tree into its linked
representation which is just how we imagined it would have looked in real life.
So, this was the representation of the binary tree we saw above using linked representation.
And what are these nodes? These are structures having three structure members, first a data
element to store the data of the node, and then two structure pointers to hold the address of
the child nodes, one for the left, and the other for the right.
How to create binary tree using C
• struct node{
• int data;
• struct node* left;
• struct node* right;
• };
• #include<stdio.h>
#include<malloc.h>
struct node{
int data;
struct node* left;
struct node* right;
};
int main(){
/*
// Constructing the root node
struct node *p;
p = (struct node *) malloc(sizeof(struct node));
p->data = 2;
p->left = NULL;
p->right = NULL;
• // Constructing the second node
struct node *p1;
p1 = (struct node *) malloc(sizeof(struct node));
p->data = 1;
p1->left = NULL;
p1->right = NULL;
• So in this traversal technique, the first node you start with is the root node. And thereafter you visit
the left subtree and then the right subtree. Taking the above example, I’ll mark your order of
traversal as below. You first visit section 1, then 2, and then 3
• Each time you get a tree, you first visit its root node, and then move to its left subtree, and then
to the right.
• So, here you first visit the root node element 7 and then move to the left subtree. The left subtree
in itself is a tree with root node 11. So, you visit that and move further to the left subtree of this
subtree. There you see a single element 7, you visit that, and then move to the right subtree
which is a NULL. So, you're finished with the left subtree of the main tree. Now, you move to the
right subtree which has element 2 as its node. And then a NULL to its left and element 9 to its
right.
• So basically, you recursively visit each subtree in the same order. And your final traversal order is:
• // Constructing the root node - Using Function (Recommended)
• struct node *p = createNode(4);
• struct node *p1 = createNode(1);
• struct node *p2 = createNode(6);
• struct node *p3 = createNode(5);
• struct node *p4 = createNode(2);
• // Finally The tree looks like this:
• // 4
• // / \
• // 1 6
• // / \
• // 5 2
• preOrder(p);
• return 0;
• }
Post Order Traversal in a Binary Tree:
• In this traversal technique, things are quite opposite to the PreOrder traversal. Here, you first visit
the left subtree, and then the right subtree. So, the last node you’ll visit is the root node. first visit
section 1, then 2, and then 3.
• Each time you get a tree, you first visit its left subtree, and then its
right subtree, and then move to its root node.
InOrder Traversal in a Binary Tree:
• In this traversal technique, we simply start with the left subtree, that
is you first visit the left subtree, and then go to the root node and
then you’ll visit the right subtree.
• Each time you get a tree, you first visit its left subtree, and then its
root node, and then finally its right subtree.
How to search a binary tree?
(1) Start at the root
(2) Search the tree level
by level, until you find
the element you are
searching for or you reach
a leaf.
No O(N)
Binary Search Trees (BSTs)
• Binary Search Tree Property:
The value stored at
a node is greater than
the value stored at its
left child and less than
the value stored at its
right child
Binary Search Trees (BSTs)
Where is the
smallest element?
Ans: leftmost element
template<class ItemType>
struct TreeNode<ItemType> {
ItemType info;
TreeNode<ItemType>* left;
TreeNode<ItemType>* right;
};
Binary Search Tree Specification
#include <fstream.h>
struct TreeNode<ItemType>;
enum OrderType {PRE_ORDER, IN_ORDER, POST_ORDER};
template<class ItemType>
class TreeType {
public:
TreeType();
~TreeType();
TreeType(const TreeType<ItemType>&);
void operator=(const TreeType<ItemType>&);
void MakeEmpty();
bool IsEmpty() const;
bool IsFull() const;
int NumberOfNodes() const;
Binary Search Tree Specification
(cont.)
void RetrieveItem(ItemType&, bool& found);
void InsertItem(ItemType);
void DeleteItem(ItemType);
void ResetTree(OrderType);
void GetNextItem(ItemType&, OrderType, bool&);
void PrintTree(ofstream&) const;
private:
TreeNode<ItemType>* root;
};
Insertion in a Binary Search Tree
There are no duplicates in a binary search tree.
Here is an example binary search tree, and the element
we want to insert is 9
• Now, you would simply start from the root node, and see if the element you want to insert is
greater than or less than. And since 9 is greater than 8, we move to the right of the root. And then
the root is the element 10, and since this time 9 is less than 10, we move to the left of it. And since
there are no elements to its left, we simply insert element 9 there.
Now, before you insert a node, the first thing you would do is to create that node and allocate memory to it in
heap using malloc. Then you would initialize the node with the data given, and both the right and the left
member of the node should be marked NULL.
And another important thing to see here is the pointer you would follow the correct position with. In the
above example, to be able to insert at that position, the pointer must be at node 10.
• void insert(struct node *root, int key){
• struct node *prev = NULL;
• while(root!=NULL){
• prev = root;
• if(key==root->data){
• printf("Cannot insert %d, already in BST", key);
• return;
• }
• else if(key<root->data){
• root = root->left;
• }
• else{
• root = root->right;
• }
• }
• struct node* new = createNode(key);
• if(key<prev->data){
• prev->left = new;
• }
• else{
• prev->right = new;
• }
•}
Deletion in a Binary Search Tree
whenever we talk about deleting a node from binary search tree, we have
the following three cases in mind:
• The node is a leaf node.
• The node is a non-leaf node.
• The node is the root node.
• Deleting a leaf node:
• Deleting a leaf node is the simplest case in deletion in binary search
trees where the only thing you have to do is to search the element in
the tree, and remove it from the tree, and make its parent node point
to NULL. To be more specific, follow the steps below to delete a leaf
node along with the illustrations of how we delete a leaf node in the
above tree:
• struct node{
• int data;
• struct node* left;
• struct node* right;
• };
• struct node* createNode(int data){
• struct node *n; // creating a node pointer
• n = (struct node *) malloc(sizeof(struct node)); // Allocating memory in the heap
• n->data = data; // Setting the data
• n->left = NULL; // Setting the left and right children to NULL
• n->right = NULL; // Setting the left and right children to NULL
• return n; // Finally returning the created node
•}
• void preOrder(struct node* root){
• if(root!=NULL){
• printf("%d ", root->data);
• preOrder(root->left);
• preOrder(root->right);
• }
•}
•int main(){
• // Constructing the root node - Using Function (Recommended)
• struct node *p = createNode(4);
• struct node *p1 = createNode(1);
• struct node *p2 = createNode(6);
• struct node *p3 = createNode(5);
• struct node *p4 = createNode(2);
• // Finally The tree looks like this:
• // 4
• // / \
• // 1 6
• // / \
• // 5 2
• // Linking the root node with left and right children
• p->left = p1;
• p->right = p2;
• p1->left = p3;
• p1->right = p4;
preOrder(p);
• return 0;
•}
Creating the postOrder function
• Now, if you remember, the height of a tree ranges from logn to n, that is
• (logn) ≤ h ≤ n
• So, the best-case time complexity is O(logn) and the worst-case time complexity is O(n).
Pseudocode for searching in a Binary Search Tree: