11 9 7 15 14 8 10 13
A:-
7
8 9
1 1 1
1
1 3 4
0
1
5
Q2.) Discuss the various application and operation of AVL trees with
example.
Ans: In computer science, an AVL tree is a self-balancing binary search tree, and it was the
first such data structure to be invented
• for every node in the tree, the height of the left and right subtrees differ by
at most 1.
The balance factor of a node is the height of its left subtree minus the height of its right
subtree (sometimes opposite) and a node with balance factor 1, 0, or −1 is considered
balanced. A node with any other balance factor is considered unbalanced and requires
rebalancing the tree. The balance factor is either stored directly at each node or computed
from the heights of the subtrees.
The basic operations of an AVL tree involve carrying out the same actions as would be
carried out on an unbalanced binary search tree, but modifications are preceded or followed
by one or more operations called tree rotations, which help to restore the height balance of
the subtrees.
• Lookup
Lookup in an AVL tree is performed exactly as in an unbalanced binary search tree. Because
of the height-balancing of the tree, a lookup takes O(log n) time. No special actions need to
be taken, and the tree's structure is not modified by lookups. (If each node additionally
records the size of its subtree (including itself and its descendants), then the nodes can be
retrieved by index in O(log n) time as well.
Once a node has been found in a balanced tree, the next or previous nodes can be explored
in amortized constant time. A few cases require traversing up to 2×log(n) links. However
exploring all n nodes in the tree in this manner would use each link exactly twice, and there
are n−1 links, so the amortized cost is 2×(n−1)/n, approximately 2.
• INSERTION:
After inserting a node, it is necessary to check each of the node's ancestors for consistency
with the rules of AVL. For each node checked, if the balance factor remains −1, 0, or +1 then
no rotations are necessary. However, if the balance factor becomes ±2 then the subtree rooted
at this node is unbalanced. If insertions are performed serially, after each insertion, at most
two tree rotations are needed to restore the entire tree to the rules of AVL.
• ROTATIONS:
Right-Right case and Right-Left case: If the balance factor of P is −2, then the right subtree
outweighs the left subtree of the given node, and the balance factor of the right child (R) must
be checked. If the balance factor of R is ≤ 0, a left rotation is needed with P as the root. If
the balance factor of R is +1, a double left rotation (with respect to P) is needed. The first
rotation is a right rotation with R as the root. The second is a left rotation with P as the root.
Left-Left case and Left-Right case: If the balance factor of P is +2, then the left subtree
outweighs the right subtree of the given node, and the balance factor of the left child (L) must
be checked. If the balance factor of L is ≥ 0, a right rotation is needed with P as the root. If
the balance factor of L is −1, a double right rotation (with respect to P) is needed. The first
rotation is a left rotation with L as the root. The second is a right rotation with P as the root.
the node is a leaf or has only one child, remove it. Otherwise, replace it with either the
largest in its left subtree (inorder predecessor) or the smallest in its right subtree (inorder
successor), and remove that node. The node that was found as a replacement has at most one
subtree.
• DELETION:
After deletion, retrace the path back up the tree (parent of the replacement) to the root,
adjusting the balance factors as needed.
As with all binary trees, a node's in-order successor is the left-most child of its right subtree,
and a node's in-order predecessor is the right-most child of its left subtree. In either case, this
node will have zero or one children.
Ans:
A double right rotation, or right-left rotation, or simply RL, is a rotation that must be
performed when attempting to balance a tree which has a left subtree, that is right heavy.
This is a mirror operation of what was illustrated in the section on Left-Right Rotations, or
double left rotations. Let's look at an example of a situation where we need to perform a
Right-Left rotation.
Ans:A DFS algorithm, as the name implies, is used to search deeper in the graph, whenever
possible. The edges are explored, out of the most recently discovered vertex v that still has
unexplored edges leaving it. When all ofv's edges have been explored, the search backtracks
to explore edges leaving the vertex from which v was discovered. This process continues
until we have discovered all the vertices that are reachable from the source vertex. DFS uses
stack structure to maintain the order in which the vertices are to be processed.
Algorithm:
Step 2: Push the starting node in stack and change its status to the waiting state (status = 2)
Step 4: pop the top node n of stack. Process n and change the status of n to the processed
state (status = 3)
Step 5: Push on to the stack, all the neighbor of n that are in ready state (status = 1), and
change their status to the waiting state (status = 2) [End of the step 3 loop]
Algorithm:
Step 1: Initialize all nodes to ready state
(status = 1)
Step 6: Exit
Ans: Different data structures for the representation of graphs are used in practice:
Adjacency list - An adjacency list is implemented as an array of lists, with one list of
destination nodes for each source node.
Incidence list - A variant of the adjacency list that allows for the description of the
edges at the cost of additional edges.
Adjacency matrix - A two-dimensional Boolean matrix, in which the rows and
columns represent source and destination vertices and entries in the matrix indicate
whether an edge exists between the vertices associated with that row and column.
Incidence matrix - A two-dimensional Boolean matrix, in which the rows represent
the vertices and columns represent the edges. The array entries indicate if both are related,
i.e. incident.
Adjacency lists are preferred for sparse graphs; otherwise, an adjacency matrix is a good
choice.
For graphs with some regularity in the placement of edges, a symbolic graph is a possible choice of
representation.
.
Implementation using linked list
#include<stdio.h>
#include<conio.h>
template
struct node
{
T data;
node *link;
};
template
class graph
{
private:
int maxsize;
node **first;
public:
void accept();
void display();
graph(int n)
{
maxsize=n;
first=new node *[maxsize];
}
graph(){}
};
template
void graph::accept()
{
node *temp,*t;
char choice;
for(int i=0;i<maxsize;i++)
{
cout<<"Enter edges for "<<i<<" vertex="" "<<endl;
t=new node;
t->link=NULL;
first[i]=t;
temp=t;
do
{ int k;
cout<<"Enter the Vertex no to which it has to connect :";
cin>>k;
if(k<maxsize)
{
t=new node;
t->data=k;
t->link=NULL;
temp->link=t;
temp=temp->link;
}
else
cout<<"Invalid vertex no "<<endl;
template
void graph::display()
{
for(int i=0;i<maxsize;i++)
{
node *t;
t=first[i];
cout<<"Vertex "<<i<<" is="" conneted="" to="" the="" vertices="" ";
while(t!=NULL)
{
cout<data<<" ";
t=t->link;
}
cout<<endl;
}
}
void main()
{
clrscr();
graph g1(5);
g1.accept();
g1.display();
getch();
}
a) Weighted Graph.
b) Directed Graph
c) Strongly Connected Graph
d) Multi Graph
Ans:
WEIGHTED GRAPH:
weighted graph is a graph in which each branch is given a numerical weight. A weighted
graph is therefore a special type of labeled graph in which the labels are numbers (which are
usually taken to be positive).
A weighted graph associates a label (weight) with every edge in the graph. Weights are
usually real numbers. They may be restricted to rational numbers or integers. Certain
algorithms require further restrictions on weights; for instance, Dijkstra's algorithm works
properly only for positive weights. The weight of a path or the weight of a tree in a
weighted graph is the sum of the weights of the selected edges.
DIRECTED GRAPH:
It differs from an ordinary or undirected graph, in that the latter is defined in terms
of unordered pairs of vertices, which are usually called edges.
A directed graph is called strongly connected if there is a path from each vertex in the graph
to every other vertex. In particular, this means paths in each direction; a path from a to b and
also a path from b to a.
The strongly connected components of a directed graph G are its maximal strongly
connected subgraphs. If each strongly connected component iscontracted to a single vertex,
the resulting graph is a directed acyclic graph, the condensation of G. A directed graph is
acyclic if and only if it has no (nontrivial) strongly connected subgraphs (because a cycle is
strongly connected, and every strongly connected graph contains at least one cycle).
MULTIGRAPH:
Multigraphs might be used to model the possible flight connections offered by an airline. In
this case the multigraph would be a directed graph with pairs of directed parallel edges
connecting cities to show that it is possible to fly both to and from these locations.
Some authors also allow multigraphs to have loops, that is, an edge that connects a vertex to
itself,[2] while others call these pseudographs, reserving the term multigraph for the case with
no loops.[3]
A multidigraph is a directed graph which is permitted to have multiple arcs, i.e., arcs with
the same source and target nodes. A multidigraph G is an ordered pair G:=(V,A) with