You are on page 1of 29

Binary Tree: A tree whose elements have at most 2 children is called a binary tree.

Since each element in a binary tree can have only 2 children, we typically name
them the left and right child.

Binary Tree Representation in C: A tree is represented by a pointer to the topmost


node in tree. If the tree is empty, then value of root is NULL.
A Tree node contains following parts.
1. Data
2. Pointer to left child
3. Pointer to right child
 In C, we can represent a tree node using structures.
 Below is an example of a tree node with an integer data.
struct node

int data;

struct node *left;


struct node *right;
};

First Simple Tree in C


Let us create a simple tree with 4 nodes in C. The created tree would be as
following.
tree

----

1 <-- root

/ \

2 3

 C Implementation of tree
struct node
{
int data;
struct node *left;
struct node *right;
};

/* newNode() allocates a new node with the given data and NULL left and
right pointers. */
struct node* newNode(int data)
{
// Allocate memory for new node
struct node* node = (struct node*)malloc(sizeof(struct node));

// Assign data to this node


node->data = data;
// Initialize left and right children as NULL
node->left = NULL;
node->right = NULL;
return(node);
}

int main()
{
/*create root*/
struct node *root = newNode(1);
/* following is the tree after above statement

1
/ \
NULL NULL
*/

root->left = newNode(2);
root->right = newNode(3);
/* 2 and 3 become left and right children of 1
1
/ \
2 3
/ \ / \
NULL NULL NULL NULL
*/

root->left->left = newNode(4);
/* 4 becomes left child of 2
1
/ \
2 3
/ \ / \
4 NULL NULL NULL
/ \
NULL NULL
*/

getchar();
return 0;
}
Properties of Binary Tree
1) The maximum number of nodes at level ‘l’ of a binary tree is 2l-1.
Here level is number of nodes on path from root to the node (including root and node). Level of root is
1.
This can be proved by induction.
For root, l = 1, number of nodes = 21-1 = 1
Assume that maximum number of nodes on level l is 2l-1
l-1
Since in Binary tree every node has at most 2 children, next level would have twice nodes, i.e. 2*2

2) Maximum number of nodes in a binary tree of height ‘h’ is 2h – 1.


Here height of a tree is maximum number of nodes on root to leaf path. Height of a leaf node is
considered as 1.
This result can be derived from point 2 above. A tree has maximum nodes if all levels have maximum
nodes. So maximum number of nodes in a binary tree of height h is 1 + 2 + 4 + .. + 2h-1. This is a
simple geometric series with h terms and sum of this series is 2h –1.
In some books, height of a leaf is considered as 0. In this convention,the above formula becomes
2h+1– 1

3) In a Binary Tree with N nodes, minimum possible height or minimum number of


levels is ⌈ Log2(N+1) ⌉
This can be directly derived from point 2 above. If we consider the convention where height of a leaf
node is considered as 0, then above formula for minimum possible height becomes ⌈ Log2(N+1) ⌉ – 1

4) A Binary Tree with L leaves has at least ⌈ Log2L ⌉ + 1 levels


A Binary tree has maximum number of leaves when all levels are fully filled. Let all leaves be at level
l, then below is true for number of leaves L.

L <= 2l-1 [From Point 1]


Log2L = ⌈ Log2L ⌉ + 1

5) In Binary tree, number of leaf nodes is always one more than nodes with two
children.
L = T + 1

Where L = Number of leaf nodes

T = Number of internal nodes with two children


Types of Binary Tree
1- Full Binary Tree or Strictly Binary Tree- A Binary Tree is full if every node has 0 or 2
children. Following are examples of full binary tree.
a) 18

/ \

15 30

/ \ / \

40 50 100 40

b) 18

/ \

15 20

/ \

40 50

/ \

30 50

c) 18

/ \

40 30

/ \

100 40

In a Full Binary, number of leaf nodes is number of internal nodes plus 1


L=I+1
Where L = Number of leaf nodes, I = Number of internal nodes

2-Complete Binary Tree or Perfect Binary Tree -- A Binary tree is Perfect Binary Tree in
which all internal nodes have two children and all leaves are at same level.
Practical example of Complete Binary Tree is Binary Heap
Following are examples of Perfect Binaryr Trees.
a) 18

/ \

15 30

/ \ / \

40 50 100 40

b) 18

/ \

15 30

 A Perfect Binary Tree of height h (where height is number of nodes on path from root to leaf)
has 2h– 1 node.
 at every level of complete binary tree there must be 2level number of nodes
Example of Perfect binary tree is ancestors in family. Keep a person at root, parents as children,
parents of parents as their children.
3. Extended Binary Tree

A binary tree can be converted into Full Binary tree by adding dummy nodes to
existing nodes wherever required.

The full binary tree obtained by adding dummy nodes to a binary tree is called as
Extended Binary Tree.

In above figure, a normal binary tree is converted into full binary tree by adding
dummy nodes (In pink colour).

4-Balanced Binary Tree


A binary tree is balanced if height of the tree is O(Log n) where n is number of nodes.
For Example, AVL tree maintain O(Log n) height by making sure that the difference between
heights of left and right subtrees is 1. Red-Black trees maintain O(Log n) height by making
sure that the number of Black nodes on every root to leaf paths are same and there are no
adjacent red nodes. Balanced Binary Search trees are performance wise good as they
provide O(log n) time for search, insert and delete.

5-A degenerate (or pathological) tree -- A Tree where every internal node has one child.
Such trees are performance-wise same as linked list.
10

20

30

40
Binary Tree (Threaded And Unthreaded ) as Data Structure
1- Threaded Binary Tree-
a) Inorder traversal of a Binary tree is either be done using recursion or with the use of a
auxiliary stack.
b) The idea of threaded binary trees is to make inorder traversal faster and do it without
stack and without recursion.
c) A binary tree is made threaded by making all right child pointers that would normally
be NULL point to the inorder successor of the node (if it exists).
d) There are two types of threaded binary trees-
1) Single Threaded: Where a NULL right pointers is made to point to the inorder
successor (if successor exists)
2) Double Threaded: Where both left and right NULL pointers are made to point to
inorder predecessor and inorder successor respectively.
The predecessor threads are useful for reverse inorder traversal and postorder traversal.
The threads are also useful for fast accessing ancestors of a node.
Following diagram shows an example Single Threaded And Double Threaded Binary Tree.
The dotted lines represent threads.

Double Threaded Binary Tree


C representation of a Threaded Node
struct Node
{
int data;
Node *left, *right;
bool rightThread;
}
Since right pointer is used for two purposes, the boolean variable rightThread is used to
indicate whether right pointer points to right child or inorder successor. Similarly, we can
add leftThread for a double threaded binary tree.
Inorder Taversal using Threads
Following is C code for inorder traversal in a threaded binary tree.
 // Utility function to find leftmost node in a tree rooted with n
struct Node* leftMost(struct Node *n)
{
if (n == NULL)
return NULL;

while (n->left != NULL)


n = n->left;

return n;
}
 // C code to do inorder traversal in a threaded binary tree
void inOrder(struct Node *root)
{
struct Node *cur = leftmost(root);
while (cur != NULL)
{
printf("%d ", cur->data);

// If this node is a thread node, then go to


// inorder successor
if (cur->rightThread)
cur = cur->rightThread;
else // Else go to the leftmost child in right subtree
cur = leftmost(cur->right);
}
}
Following diagram demonstrates inorder order traversal using threads.

2-Unthreaded Binary Tree


Inorder Non-threaded Binary Tree Traversal without Recursion or Stack
* We can do inorder traversal without threads if we have parent pointers available to us.
Input: Root of Below Tree [Every node of

tree has parent pointer also]


10

/ \

5 100

/ \

80 120

Output: 5 10 80 100 120


The code should not extra space (No Recursion

and stack)

 In inorder traversal, we follow “left root right”. We can move to children using left and right
pointers. Once a node is visited, we need to move to parent also. For example, in the above
tree, we need to move to 10 after printing 5. For this purpose, we use parent pointer.
 Below is algorithm.

1. Initialize current node as root

2. Initialize a flag: leftdone = false;


3. Do following while root is not NULL
a) If leftdone is false, set current node as leftmost
child of node.
b) Mark leftdone as true and print current node.
c) If right child of current nodes exists, set current
as right child and set leftdone as false.
d) Else If parent exists, If current node is left child
of its parent, set current node as parent.
If current node is right child, keep moving to ancestors
using parent pointer while current node is right child
of its parent.
e) Else break (We have reached back to root)

Illustration:
Let us consider below tree for illustration.

10

/ \

5 100

/ \

80 120

Description of Illustration

1-Initialize: Current node = 10, leftdone = false

2-Since leftdone is false, we move to 5 (3.a), print it

and set leftdone = true.

3-Now we move to parent of 5 (3.d). Node 10 is

printed because leftdone is true.

4-We move to right of 10 and set leftdone as false (3.c)

5-Now current node is 100. Since leftdone is false, we move

to 80 (3.a) and set leftdone as true. We print current node 80 and move back to parent 100
(3.d). Since leftdone

is true, we print current node 100.

6-Right of 100 exists, so we move to 120 (3.c). We print

current node 120.

7-Since 120 is right child of its parent we keep moving to parent

while parent is right child of its parent. We reach root. So


we break the loop and stop

Insertion , Deletion and Traversal Of Binary Trees


1)Insertion in a Binary Tree
Steps For Inserting a Key in a Binary Tree :
 If we find a node whose left child is empty, we make new key as left child of the node.
 Else if we find a node whose right child is empty, we make new key as right child.
 We keep traversing the tree until we find a node whose either left or right is empty.
Example-Given a binary tree and a key (12), insert the key (12) into the binary tree at first position
available in level order.

 C++ program to insert element in binary tree


#include <iostream>

#include <queue>

using namespace std;

/* A binary tree node has key, pointer to left child

and a pointer to right child */

struct Node {

int key;

struct Node* left, *right;

};

/* function to create a new node of tree and r

eturns pointer */

struct Node* newNode(int key)

struct Node* temp = new Node;

temp->key = key;

temp->left = temp->right = NULL;


return temp;

};

/* Inorder traversal of a binary tree*/

void inorder(struct Node* temp)

if (!temp)

return;

inorder(temp->left);

cout << temp->key << " ";

inorder(temp->right);

/*function to insert element in binary tree */

void insert(struct Node* temp, int key)

queue<struct Node*> q;

q.push(temp);

// Do level order traversal until we find

// an empty place.

while (!q.empty()) {

struct Node* temp = q.front();

q.pop();

if (!temp->left) {

temp->left = newNode(key);

break;

else q.push(temp->left);

if (!temp->right) {

temp->right = newNode(key);

break;

} else q.push(temp->right);

}
// Driver code

int main()

struct Node* root = newNode(10);

root->left = newNode(11);

root->left->left = newNode(7);

root->right = newNode(9);

root->right->left = newNode(15);

root->right->right = newNode(8);

cout << "Inorder traversal before insertion:";

inorder(root);

int key = 12;

insert(root, key);

cout << endl;

cout << "Inorder traversal after insertion:";

inorder(root);

return 0;

Output:

Inorder traversal before insertion: 7 11 10 15 9 8

Inorder traversal after insertion: 7 11 12 10 15 9 8

2-Deletion in a Binary Tree


Given a binary tree, delete a node from it by making sure that tree shrinks from the bottom (the
deleted not is replaced by bottommost and rightmost node).

Algorithm or Steps to delete a node or key from a binary tree


1. Starting at root, find the deepest and rightmost node in binary tree and node which we want to
delete.
2. Replace the deepest rightmost node’s data with node to be deleted.
3. Then delete the deepest rightmost node.
 C++ program to delete element in binary tree
#include <bits/stdc++.h>

using namespace std;

/* A binary tree node has key, pointer to left

child and a pointer to right child */

struct Node

int key;

struct Node* left, *right;

};

/* function to create a new node of tree and

return pointer */

struct Node* newNode(int key)

struct Node* temp = new Node;

temp->key = key;

temp->left = temp->right = NULL;

return temp;

};

/* Inorder traversal of a binary tree*/

void inorder(struct Node* temp)

if (!temp)

return;

inorder(temp->left);
cout << temp->key << " ";

inorder(temp->right);

/* function to delete the given deepest node

(d_node) in binary tree */

void deletDeepest(struct Node *root,

struct Node *d_node)

queue<struct Node*> q;

q.push(root);

// Do level order traversal until last node

struct Node* temp;

while(!q.empty())

temp = q.front();

q.pop();

if (temp->right)

if (temp->right == d_node)

temp->right = NULL;

delete(d_node);

return;

else q.push(temp->right);

if (temp->left)

if (temp->left == d_node)

temp->left=NULL;

delete(d_node);

return;

}
else q.push(temp->left);

/* function to delete element in binary tree */

void deletion(struct Node* root, int key)

queue<struct Node*> q;

q.push(root);

struct Node *temp;

struct Node *key_node = NULL;

// Do level order traversal to find deepest

// node(temp) and node to be deleted (key_node)

while (!q.empty())

temp = q.front();

q.pop();

if (temp->key == key)

key_node = temp;

if (temp->left)

q.push(temp->left);

if (temp->right)

q.push(temp->right);

int x = temp->key;

deletDeepest(root, temp);

key_node->key = x;

// Driver code

int main()

struct Node* root = newNode(10);


root->left = newNode(11);

root->left->left = newNode(7);

root->left->right = newNode(12);

root->right = newNode(9);

root->right->left = newNode(15);

root->right->right = newNode(8);

cout << "Inorder traversal before deletion : ";

inorder(root);

int key = 11;

deletion(root, key);

cout << endl;

cout << "Inorder traversal after deletion : ";

inorder(root);

return 0;

Output:

Inorder traversal before deletion : 7 11 12 10 15 9 8

Inorder traversal after deletion : 7 8 12 10 15 9

3-Tree Traversals (Inorder, Preorder and Postorder)


 Unlike linear data structures (Array, Linked List, Queues, Stacks, etc) which have only one
logical way to traverse them.
 trees can be traversed in different ways. Following are the generally used ways for traversing
trees.

Example Tree

Depth First Traversals:

(a) Inorder (Left, Root, Right) : 4 2 5 1 3

(b) Preorder (Root, Left, Right) : 1 2 4 5 3

(c) Postorder (Left, Right, Root) : 4 5 2 3 1

Breadth First or Level Order Traversal : 1 2 3 4 5


One more example:

(i) Inorder Traversal:


Algorithm Inorder(tree)

1. Traverse the left subtree, i.e., call Inorder(left-subtree)

2. Visit the root.

3. Traverse the right subtree, i.e., call Inorder(right-subtree)

Uses of Inorder
 In case of binary search trees (BST), Inorder traversal gives nodes in non-decreasing order.
 To get nodes of BST in non-increasing order, a variation of Inorder traversal where Inorder
traversal is reversed, can be used.
 Example: Inorder traversal for the above given figure is 4 2 5 1 3.

(ii)Preorder Traversal:
Algorithm Preorder(tree)

1. Visit the root.

2. Traverse the left subtree, i.e., call Preorder(left-subtree)

3. Traverse the right subtree, i.e., call Preorder(right-subtree)

Uses of Preorder
 Preorder traversal is used to create a copy of the tree.
 Preorder traversal is also used to get prefix expression on of an expression tree.
 Example: Preorder traversal for the above given figure is 1 2 4 5 3.

(iii)Postorder Traversal:
Algorithm Postorder(tree)

1. Traverse the left subtree, i.e., call Postorder(left-subtree)

2. Traverse the right subtree, i.e., call Postorder(right-subtree)


3. Visit the root.

Uses of Postorder
 Postorder traversal is used to delete the tree.
 Postorder traversal is also useful to get the postfix expression of an expression tree.
 Example: Postorder traversal for the above given figure is 4 5 2 3 1.

 C program for different tree traversals


#include <stdio.h>
#include <stdlib.h>
/* A binary tree node has data, pointer to left child
and a pointer to right child */
struct node
{
int data;
struct node* left;
struct node* right;
};
/* Helper function that allocates a new node with the
given data and NULL left and right pointers. */
struct node* newNode(int data)
{
struct node* node = (struct node*)
malloc(sizeof(struct node));
node->data = data;
node->left = NULL;
node->right = NULL;
return(node);
}
/* Given a binary tree, print its nodes according to the
"bottom-up" postorder traversal. */
void printPostorder(struct node* node)
{
if (node == NULL)
return;
// first recur on left subtree
printPostorder(node->left);
// then recur on right subtree
printPostorder(node->right);
// now deal with the node
printf("%d ", node->data);
}
/* Given a binary tree, print its nodes in inorder*/
void printInorder(struct node* node)
{
if (node == NULL)
return;
/* first recur on left child */
printInorder(node->left);
/* then print the data of node */
printf("%d ", node->data);
/* now recur on right child */
printInorder(node->right);
}
/* Given a binary tree, print its nodes in preorder*/
void printPreorder(struct node* node)
{
if (node == NULL)
return;
/* first print data of node */
printf("%d ", node->data);
/* then recur on left sutree */
printPreorder(node->left);
/* now recur on right subtree */
printPreorder(node->right);
}
/* Driver program to test above functions*/
int main()
{
struct node *root = newNode(1);
root->left = newNode(2);
root->right = newNode(3);
root->left->left = newNode(4);
root->left->right = newNode(5);
printf("\nPreorder traversal of binary tree is \n");
printPreorder(root);
printf("\nInorder traversal of binary tree is \n");
printInorder(root);
printf("\nPostorder traversal of binary tree is \n");
printPostorder(root);
getchar();
return 0;
}

Output:

Preorder traversal of binary tree is

1 2 4 5 3

Inorder traversal of binary tree is

4 2 5 1 3

Postorder traversal of binary tree is

4 5 2 3 1
Constructing Binary Tree From Traversal Result-

*We can construct a binary tree if we are given at least two traversal results. The first
traversal must be the in-order traversal and the second can be either pre-order or post-
order traversal.
* The in-order traversal result will be used to determine the left and the right child nodes, and
the
* pre-order/post-order can be used to determine the root node. For example, consider the
traversal results given below:

Inorder-INFORMATION

Postorder-INOFMAINOTR

Pre–order Traversal: A B D E C F G

In–order Traversal: DBEAFCG

Here, we have the in-order traversal sequence and pre-order traversal sequence. Follow the
steps given below to construct the tree:

Step 1 Determine Root

In Pre-Order the first element, in Post-Order the last element is the root node.

PreOrder-Root node ←A B D E C F G

PostOrder-INOFMAINOTR→ Root node

Step 2 Determine Subtree

Elements on the left side of the root node in the in-order traversal form the left sub-tree of the
root node. Similarly, elements on the right side of the root node in the in-order traversal
sequence form the right sub-tree of the root node.

(left subtree) D B E A F C G (right subtree)

(left subtree) INFO R MATION(right subtree)

Step 3

Preorder- Recursively select each element from pre-order traversal(make its parent node) ,
from left to right and create its left and right sub-trees from the in-order traversal.

Postorder- Recursively select each element from post-order traversal, from right to left and
create its left and right sub-trees from in-order traversal.
Example 1- of In-order and Post-Order Traversal

In–order Traversal: D B H E I A F J C G

Post-order Traversal: D H E B I J F G C

*underlined letters are considered parent node

Example 2- of In-order and Post-Order Traversal


Inorder- INFORMATION
Postorder- INOFMAINOTR
*underlined letters are considered parent node

AVL Tree
1-The AVL tree was introduced in the year of 1962 by G.M. Adelson-Velsky and
E.M. Landis.
2-AVL tree is a self balanced binary search tree. That means, an AVL tree is also a
binary search tree but it is a balanced tree.
3-A binary tree is said to be balanced, if the difference between the hieghts of
left and right subtrees of every node in the tree is either -1, 0 or +1.
In other words, a binary tree is said to be balanced if for every node, height of its
children differ by at most one.
4-In an AVL tree, every node maintains a extra information known as balance
factor.

5-An AVL tree is defined as follows...

An AVL tree is a balanced binary search tree. In an AVL tree, balance factor of
every node is either -1, 0 or +1.

6-Balance Factor- Balance factor of a node is the difference between the heights
of left and right subtrees of that node. The balance factor of a node is calculated
either height of left subtree - height of right subtree (OR) height of right subtree -
height of left subtree.
In the following explanation, we are calculating as follows...

Balance factor = heightOfLeftSubtree - heightOfRightSubtree


Example

 The above tree is a binary search tree and every node is satisfying balance
factor condition. So this tree is said to be an AVL tree.
 Every AVL Tree is a binary search tree but all the Binary Search Trees need
not to be AVL trees.

Operations on an AVL Tree


The following operations are performed on an AVL tree...
1-Search
2-Insertion
3-Deletion

1-Search Operation in AVL Tree


In an AVL tree, the search operation is performed with O(log n) time complexity.
The search operation is performed similar to Binary search tree search operation.
We use the following steps to search an element in AVL tree...

 Step 1: Read the search element from the user


 Step 2: Compare, the search element with the value of root node in the
tree.
 Step 3: If both are matching, then display "Given node found!!!" and
terminate the function
 Step 4: If both are not matching, then check whether search element is
smaller or larger than that node value.
 Step 5: If search element is smaller, then continue the search process in
left subtree.
 Step 6: If search element is larger, then continue the search process in right
subtree.
 Step 7: Repeat the same until we found exact element or we completed
with a leaf node
 Step 8: If we reach to the node with search value, then display "Element is
found" and terminate the function.
 Step 9: If we reach to a leaf node and it is also not matching, then display
"Element not found" and terminate the function.

2-Insertion Operation in AVL Tree


In an AVL tree, the insertion operation is performed with O(log n) time
complexity. In AVL Tree, new node is always inserted as a leaf node. The insertion
operation is performed as follows...

 Step 1: Insert the new element into the tree using Binary Search Tree
insertion logic.
 Step 2: After insertion, check the Balance Factor of every node.
 Step 3: If the Balance Factor of every node is 0 or 1 or -1 then go for next
operation.
 Step 4: If the Balance Factor of any node is other than 0 or 1 or -1 then
tree is said to be imbalanced. Then perform the suitable Rotation to make
it balanced. And go for next operation.

Example: Construct an AVL Tree by inserting numbers from 1 to 8.


3-Deletion from AVL Tree
* Delete a node x as in ordinary binary search tree

(a)Note that the last (deepest) node in a tree deleted is a leaf or a node with one
child

* Then trace the path from the new leaf towards the root
* For each node x encountered, check if heights of left(x) and right(x) differ by at most
1.

I. If yes, proceed to parent(x)


II. If no, perform an appropriate rotation at x Continue to trace the path until
we reach the root
Applications of trees for representation of sets-
1 Sets as Trees
If we represent a set as a balanced tree we can achieve a significant speed up in evaluating
the member_set? and adjoin functions.

We speak of the tree as being composed of nodes, each of which contains an entry which is a
member of the set being represented, a left branch and a right branch. A tree is a binary
search tree with respect to a given total ordering relation if the entry at any node is greater
than all entries occurring in the left branch, and less than all entries occurring in the right
branch. This is the first data invariant for our representation of sets as trees.

A tree can also be an empty-tree, which has no entry, left branch or right branch.

The height of a tree is defined as being 0 for the empty tree, and one more than the maximum
of the height of the left branch and the height of right branch for a non-empty tree.

The great advantage of a binary search tree is that, if we are looking for a given entry, x in a
tree, we can compare x with the entry, y say, to find which sub-tree x must lie in.
If x=y then x is in the tree, and we have found it. If x<y then we know that it must lie in the
left branch of the tree if it is in the tree at all, and conversely, if x>y then it must lie in the
right branch. If the tree is adequately balanced, then at each stage we are dividing the size of
the set of values in which we are searching by 2, which means that our search for x will
terminate in logarithmic time.

1.2 Well balanced trees

However we may not have a set of size exactly 2h+1 - 1 elements. Such a set cannot be
represented by a perfectly balanced tree, but we can limit the amount of unbalance to
maintain logarithmic time access.

Any set can be represented by a tree in which the disparity between the number of entries in
the left branch and the number in the right branch is never more than 1. The algorithm to do
this is obvious enough:
 If the set has an odd number of elements take the median element as the entry of
the tree, and recursively make a left sub-tree of all elements less than the median,
and a right sub-tree of all elements greater than the median.
 If the set has an even number of elements, take one of the 2 elements nearest the
median, and recursively make left and right sub-trees less than and greater than this
element.

Let us call such a tree "well-balanced". If we kept our trees well-balanced, then this would
give us the shortest worst-case time to find a given element in a member_set? operation.

However, maintaining trees in a well-balanced form is not practicable if we want an efficient


implementation of adjoin. Imagine a well-balanced tree

where A and B are subtrees, and size(B) = size(A) + 1. If we now adjoin an


element y > x, y < b for all b in B, to the tree, B becomes one larger, but the
rearrangement required to maintain the well-balanced condition can be quite expensive.

Consider, for example the tree:

Adjoin 7 - a simple algorithm gives:

Adjust to make it well balanced:


It is clear from this example that we have a significant amount of work to do. The 7 has
moved from a tip of the tree to the root-node, while the 6 has moved from the root-node to a
tip. This kind of re-arrangement could take place in many circumstances in which an entry
which "belongs" between the left and right branches is adjoined to a tree of any depth.

You might also like