Top Banner
Homework Title / No. : 4 Course Code : CAP205 Course Instructor : Lect. Sanjay Sood Student’s Roll :- RD3912A10 Section No. : D3912 Declaration: I declare that this assignment is my individual work. I have not copied from any other student’s work or from any other source except where due acknowledgment is made explicitly in the text, nor has any part been written for me by another person. Student’s Signature : Baninder
29

data structure 4th asgmt

Apr 04, 2015

Download

Documents

nancy_01
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: data structure 4th asgmt

Homework Title / No. : 4 Course Code : CAP205

Course Instructor : Lect. Sanjay Sood Student’s Roll :- RD3912A10

Section No. : D3912

Declaration: I declare that this assignment is my individual work. I have not copied from any other student’s work or from any other source except where due acknowledgment is made explicitly in the text, nor has any part been written for me by another person.

Student’s Signature : Baninder

Page 2: data structure 4th asgmt

Evaluator’s comments: _____________________________________________________________________ Marks obtained : ___________ out of ______________________

1. Sort the given List using Heap Sort Technique :

11 9 7 15 14 8 10 13

Sol:- (a) item= 11

(b) item= 9

(a) item= 7

(b)item= 1

11

11

9

11

9 7

Page 3: data structure 4th asgmt

(c) item= 14

(g) item=8

(d)item=10

15

11

9

7

15

14

9

7

11

15

14

9

8

117

15

14

9

10

117 8

Page 4: data structure 4th asgmt

(e) item= 13

Now sorting the heap we get:-

2. Discuss the various application and operation of AVL trees with example.

A:- An AVL tree is a self-balancing binary search tree, and it is the first such data structure to be invented.

In an AVL tree, the heights of the two child subtrees of any node differ by at most one; therefore, it is also said to be height-balanced. Lookup, insertion, and deletion all take O(log n) time in both the average and worst cases, where n is the number of nodes in the tree prior to the operation. Insertions and deletions may require the tree to be rebalanced by one or more tree rotations.

• For every node the left and right side differ in height by less than two.• The left and right side are themselves AVL trees.• An AVL Tree is a binary search tree such that for every internal node v of T, the

heights of the children of v can differ by at most 1.

15

14

13

10

117 8

9

7

8 9

10

11

13

14

15

Page 5: data structure 4th asgmt

88

44

17 78

32 50

48 62

2

4

1

1

2

3

1

1

An example of an AVL tree where the heights are shown next to the nodes:

Properties of AVL trees:-

1. The height of an AVL tree with n nodes is O(log n)2. For every value of n, n ³ 0, there exists an AVL tree3. An n-node AVL search tree can be searched in O(height) = O(log n) time4. A new node can be inserted into an n-node AVL search tree so that the result is an

n+1 node AVL tree and insertion can be done in O(log n) time5. A node can be deleted from an n-node AVL search tree, n>0, so that the result is an n-

1 node AVL tree and deletion can be done in O(log n) time

Operations

The basic operations of an AVL tree generally involve carrying out the same actions as would be carried out on an unbalanced binary search tree, but preceded or followed by one or more operations called tree rotations, which help to restore the height balance of the subtrees.

Insertion

Insertion into an AVL tree may be carried out by inserting the given value into the tree as if it were an unbalanced binary search tree, and then retracing one's steps toward the root updating the balance factor of the nodes.

If the balance factor becomes -1, 0, or 1 then the tree is still in AVL form, and no rotations are necessary.

If the balance factor becomes 2 or -2 then the tree rooted at this node is unbalanced, and a tree rotation is needed. At most a single or double rotation will be needed to balance the tree.

There are basically four cases which need to be accounted for, of which two are symmetric to the other two. For simplicity, the root of the unbalanced subtree will be called P, the right child of that node will be called R, and the left child will be called L.

If the balance factor of P is 2, it means that the right subtree outweighs the left subtree of the given node, and the balance factor of the right child (R) must then be checked. If the balance factor of R is 1, it means the insertion occurred on the (external) right side of that node and a left rotation is needed (tree rotation) with P as the root.

Page 6: data structure 4th asgmt

If the balance factor of R is -1, this means the insertion happened on the (internal) left side of that node. This requires a double rotation. The first rotation is a right rotation with R as the root. The second is a left rotation with P as the root.

The other two cases are identical to the previous two, but with the original balance factor of -2 and the left subtree outweighing the right subtree.[1] [2] [3]

Only the nodes traversed from the insertion point to the root of the tree need be checked, and rotations are a constant time operation, and because the height is limited to O(log(n)), the execution time for an insertion is O(log(n)).

Deletion

If the node is a leaf, remove it. If the node is not a leaf, 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 replacement has at most one subtree. After deletion retrace the path back up the tree (parent of the replacement) to the root, adjusting the balance factors as needed.

The retracing can stop if the balance factor becomes -1 or 1 indicating that the height of that subtree has remained unchanged.

If the balance factor becomes 0 then the height of the subtree has decreased by one and the retracing needs to continue. If the balance factor becomes -2 or 2 then the subtree is unbalanced and needs to be rotated to fix it.

If the rotation leaves the subtree's balance factor at 0 then the retracing towards the root must continue since the height of this subtree has decreased by one. This is in contrast to an insertion where a rotation resulting in a balance factor of 0 indicated that the subtree's height has remained unchanged.

The time required is O(log(h)) for lookup plus maximum O(log(h)) rotations on the way back to the root; so the operation can be completed in O(log n) time.

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 provisions 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.

Representation with example:-

INSERTION IN AN AVL TREE

• Insertion is as in a binary search tree• Always done by expanding an external node.

Page 7: data structure 4th asgmt

• Example:

Insertion example

TRINODE RESTRUCTURING

• let (a,b,c) be an inorder listing of x, y, z• perform the rotations needed to make b the topmost node of the three

Page 8: data structure 4th asgmt

Removal in an AVL Tree

• Removal begins as in a binary search tree, which means the node removed will become an empty external node. Its parent, w, may cause an imbalance.

Rebalancing after a Removal

• Let z be the first unbalanced node encountered while travelling up the tree from w. Also, let y be the child of z with the larger height, and let x be the child of y with the larger height.

• We perform restructure(x) to restore balance at z.• As this restructuring may upset the balance of another node higher in the tree, we

must continue checking for balance until the root of T is reached

Page 9: data structure 4th asgmt

Running Times for AVL Trees

• a single restructure is O(1)– using a linked-structure binary tree

• find is O(log n)– height of tree is O(log n), no restructures needed

• insert is O(log n)– initial find is O(log n)– Restructuring up the tree, maintaining heights is O(log n)

• remove is O(log n)– initial find is O(log n)– Restructuring up the tree, maintaining heights is O(log n)

3. Discuss RL rotation in AVL trees with example.

A:- A RL double rotation is to rotate something to the right, and then its former parent to the left.

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. Exp:- c /a \ b

In this situation, we have a tree that is unbalanced. The left subtree has a height of 2, and the right subtree has a height of 0. This makes the balance factor of our root node, c, equal to -2. a \ c /b

Page 10: data structure 4th asgmt

Now we have a tree that has a balance of 2. It would appear that we did not accomplish much. c /a \ b

The reason our right rotation did not work, is because the left subtree, or 'a', has a positive balance factor, and is thus right heavy. Performing a right rotation on a tree that has a left subtree that is right heavy will result in the problem we just witnessed. Now we have to make our left subtree left-heavy. We do this by performing a left rotation our left subtree. Doing so leaves us with this situation:

c / b /a

This is a tree which can now be balanced using a single right rotation. We can now perform our right rotation rooted at C. The result:

b / \a c

Balance at last.

So, it follows the rotation as follows:-

Example:-

Page 11: data structure 4th asgmt

4. Discuss the implementation of DFS and BFS with Example.• A:- DFS follows the following rules:

1. Select an unvisited node x, visit it, and treat as the current node 2. Find an unvisited neighbor of the current node, visit it, and make it the new

current node; 3. If the current node has no unvisited neighbors, backtrack to the its parent, and

make that parent the new current node; 4. Repeat steps 3 and 4 until no more nodes can be visited. 5. If there are still unvisited nodes, repeat from step 1.

Illustration of DFS

Algorithmic Steps 1. Step 1: Push the root node in the Stack.2. Step 2: Loop until stack is empty.3. Step 3: Peek the node of the stack.4. Step 4: If the node has unvisited child nodes, get the unvisited child node, mark it as

traversed and push it on stack.5. Step 5: If the node does not have any unvisited child nodes, pop the node from the

stack.

Implementation of DFS

– the last node visited is the first node from which to proceed.

Page 12: data structure 4th asgmt

– Also, the backtracking proceeds on the basis of "last visited, first to backtrack too". – This suggests that a stack is the proper data structure to remember the current node and how

to backtrack.

public void dfs{

// DFS uses Stack data structureStack s=new Stack();s.push(this.rootNode);rootNode.visited=true;printNode(rootNode);while(!s.isEmpty()){

Node n=(Node)s.peek();Node child=getUnvisitedChildNode(n);if(child!=null){

child.visited=true;printNode(child);s.push(child);

}else{

s.pop();}

}//Clear visited property of nodesclearNodes();

}

Breadth-First Search

• BFS follows the following rules: 1. Select an unvisited node x, visit it, have it be the root in a BFS tree being

formed. Its level is called the current level. 2. From each node z in the current level, in the order in which the level nodes

were visited, visit all the unvisited neighbors of z. The newly visited nodes from this level form a new level that becomes the next current level.

3. Repeat step 2 until no more nodes can be visited. 4. If there are still unvisited nodes, repeat from Step 1.

Algorithmic Steps 1. Step 1: Push the root node in the Queue.2. Step 2: Loop until the queue is empty.3. Step 3: Remove the node from the Queue.4. Step 4: If the removed node has unvisited child nodes, mark them as visited and insert

the unvisited children in the queue.

Simulation of DFS

Page 13: data structure 4th asgmt

IMPLEMENTATION

– the first node visited in each level is the first node from which to proceed to visit new nodes.

public void bfs{

// BFS uses Queue data structureQueue q=new LinkedList();q.add(this.rootNode);printNode(this.rootNode);rootNode.visited=true;while(!q.isEmpty()){

Node n=(Node)q.remove();Node child=null;while((child=getUnvisitedChildNode(n))!=null){

child.visited=true;printNode(child);q.add(child);

}}//Clear visited property of nodesclearNodes();

}

Here represents the depth first search:-

5. Discuss the implementation of Graph using arrays and link list.

Page 14: data structure 4th asgmt

A:- Array ImplementationConsider is an array implementation. It's easy to store each vertex in an array: -------------------------------| A | B | C | D | E | F | ... |------------------------------- 0 1 2 3 4 5 ...

Likewise, the edges can be stored using something called an adjacency matrix. Essentially, it represents which vertices are adjacent, or rather, which pairs of vertices have an edge. For example, the adjacency matrix for our original graph would be:

Adjacency matrix:

A B C D E F +-----------------A| 0 1 0 1 0 0B| 0 0 0 0 0 0C| 0 0 0 0 0 1D| 0 1 0 0 1 0E| 0 1 0 0 0 0F| 0 0 1 0 0 0

Each position represents whether one vertex is connected to another (value 1 = true) or not (value 0 = false). Note that it encodes the direction of the edges. For example, since there is a 1 in row A, column B, there is an edge from A to B. Since there is no edge in the reverse direction (from B to A), row B, column A has a 0.

Of course, this adjacency matrix could be represented by a 2-dimensional array.

The drawback to this approach lies in that we want to add vertices. Adding vertices would require either making the 2 arrays (vertex and adjacency array) some large maximum size OR reallocating new arrays and copying the contents from the old to the new.

Aside: As another drawback, graphs with few edges would have a lot of zeroes in the adjacency matrix, thus wasting space.

As we've seen before, data structures that need to grow like this are sometimes better implemented with linked representations.

Linked Implementation

Another way to implement a graph is to used a linked-list-like representation.

First, we need to store the element (the information at each vertex), so it's easy to put that in some kind of node...

a vertex node's data-------| A |

Page 15: data structure 4th asgmt

-------

We also need to represent the vertices that A is connected to (i.e., the edges from A). Since we don't know how many edges that will be, we can use a linked list to store a list of edges, as in:

a vertex node-------| A ||-----| --------- ---------| --+---> | B | --+---> | D | 0 |------- --------- --------- \ / edge nodes

2 points should be made:

For vertices, we need to store the element at that vertex. In contrast, for an edge, we just need to store a reference to the vertex it is connected to (we don't need all the information about that vertex). Thus, vertex nodes and edge nodes are different things.

In the above edge that goes to B for example, since we don't want to replicate all the information stored about B in this edge node, that reference to B should really be a pointer to the vertex node with B, as in:

-------| A ||-----| --------- ---------| --+---> | | | --+---> | D | 0 |------- --+------ --------- | +--------+ | v-------| B ||-----| <-- vertex node for B| 0 |-------

That's what we'll do, however, since that will end up making our drawings very complicated, we'll stick to drawing:

-------| A ||-----| --------- ---------| --+---> | B | --+---> | D | 0 |------- --------- ---------

So, now for each vertex we have something like:

-------

Page 16: data structure 4th asgmt

| A ||-----| --------- ---------| --+---> | B | --+---> | D | 0 |------- --------- ---------

-------| B ||-----|| 0 |-------

...

-------| F ||-----| ---------| --+---> | C | 0 |------- ---------

Now, even though we can get from one particular vertex to its adjacent vertices, we still need some way to get to one vertex to begin with. Thus, we need a pointer to some initial vertex, as in:

| v-------| A ||-----| --------- ---------| --+---> | B | --+---> | D | 0 |------- --------- ---------

Since the graph can have more than one component (i.e., disconnected part) AND because we are not guaranteed to be able to get to all other vertices from an arbitrary vertex in a component (e.g., from B we can't get to A), we need some other way to be able to access all vertices.

One solution is to join them into a linked list. Here's our current version of the representation:

| v-------| A ||-----| --------- ---------| --+---> | B | --+---> | D | 0 ||-----| --------- ---------| | |---+--- | v-------

Page 17: data structure 4th asgmt

| B ||-----|| 0 ||-----|| | |---+--- | v-------| C ||-----| ---------| --+---> | F | 0 ||-----| ---------| | |---+--- | v-------| D ||-----| --------- ---------| --+---> | E | --+---> | B | 0 ||-----| --------- ---------| | |---+--- | v-------| E ||-----| ---------| --+---> | B | 0 ||-----| ---------| | |---+--- | v-------| F ||-----| ---------| --+---> | C | 0 ||-----| ---------| 0 |-------

Link list representation of graphs:-

Page 18: data structure 4th asgmt

GRAPH IMPLEMENTATION USING LINKED LIST

#include<stdio.h>#include<conio.h>typedef struct vnode{int vname;struct vnode *vlink;struct enode *elink;}vnode;typedef struct enode{int vname;int eweight;struct enode *elink;}enode;vnode *adjlist=NULL;vnode* getvnode();enode* getenode();void insertvertex();void insertedge(int vstart,int vend);void creategraph();void viewgraph();void display_menu();void main(){char choice='y';int ch,vs,ve,vd,vi;display_menu();while((choice=='y')||(choice=='y')){printf("\n?");fflush(stdin);scanf("%d",&ch);switch(ch){case 0 :display_menu();break;

Page 19: data structure 4th asgmt

case 1:creategraph();break;case 2:insertvertex();break;case 3:printf("\n enter tne starting & ending vertex to insert edge:");scanf("%d%d",&vs,&ve);insertedge(vs,ve);break;case 4:viewgraph();break;default:printf("end of run ur program");exit(0);}}}vnode *getvnode(){int size;vnode *newvnode;size=sizeof(vnode);newvnode=(vnode *)malloc(size);newvnode->vlink=NULL;newvnode->elink=NULL;return(newvnode);}enode* getenode(){int size;enode *newenode;size=sizeof(enode);newenode=(enode*)malloc(size);newenode->elink=NULL;return(newenode);}void insertvertex(){vnode *tv,*nv;nv=getvnode();nv->vname=1;if(adjlist==NULL){adjlist=nv;return;}for(tv=adjlist;tv->vlink!=NULL;tv=tv->vlink);tv->vlink=nv;nv->vname=tv->vname+1;

Page 20: data structure 4th asgmt

}void insertedge(int vstart,int vend){vnode *pv;enode *te,*pe;for (pv=adjlist;pv!=NULL&&pv->vname!=vstart;pv=pv->vlink);if(pv==NULL)return;te=getenode();printf("enter edge weight from v%d to bv%d:",vstart,vend);scanf("%d",&te->eweight);te->vname=vend;if(pv->elink==NULL){pv->elink=te;return;}for(pe=pv->elink;pe->elink!=NULL;pe=pe->elink);pe->elink=te;}void creategraph(){int r,c,v,nvertex;printf("\n enter the no of vertices:");scanf("%d",&nvertex);adjlist=NULL;for(v=0;v<nvertex;v++)insertvertex();for(r=0;r<nvertex;r++)for(c=0;c<nvertex;c++)if(r!=c)insertedge(r+1,c+1);}void viewgraph()int edges=0,wstatus=0,nvertex=0;vnode *pv; enode *pe;for(pv=adjlist;pv!=NULL;pv=pv->vlink){printf("\nv%d-2d to",pv->vname);nvertex++;for(pe=pv->elink;pe!=NULL;pe=pe->elink){edges++;printf("v%d-2d(%d)->",pe->vname,pe->eweight);if(pe->eweight>1)wstatus=1;}printf("NULL");}if(adjlist!=NULL)

Page 21: data structure 4th asgmt

{printf("\n %s graph",(wstatus)?"weighted":"unweighted");printf("\n number of vertices:%5d",nvertex);printf(" \n number of edges :%5d",edges);}}void display_menu(){printf("\n\n basic operation in an adjacent list");printf("\n\t 0.display menu");printf("\n\t 1. creation of a graph");printf("\n\t 2.insert a vertex");printf("\n\t 3.insert an edge");printf("\n\t 4.view the graph");printf("\n\t 5.exit");}

6. Write Short Notes on the following:

a) Weighted Graph.b) Directed Graphc) Strongly Connected Graphd) Multi Graph.

A:- Weighted Graph

Weighted Graph is a graph for which each edge has an associated weight, usually given by a weight function w: E ® R.Sometimes want to associate some value with the edges in graph.

So.. label all the edges with a number. That number (called the weight) could represent:• Distances between two locations (cities;computers on network)• Time taken to get from one node to another (stations; states in schedule or plan).• Cost of traversing the edge (train fares; cost of wires)

Weighted graphs can be directed or undirected, cyclic or acyclic etc as unweighted graphs.

Page 22: data structure 4th asgmt

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

The number of edges with one endpoint on a given vertex is called that vertex's degree. In a directed graph, the number of edges that point to a given vertex is called its in-degree, and the number that point from it is called its out-degree.

In a directed graph, or digraph, each edge is an ordered pair of vertices – it has a direction defined.

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.

Strongly Connected Graph

A directed graph is strongly connected if there is a directed path from any node to any other node.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.

Page 23: data structure 4th asgmt

Multi Graph

Multigraph is an undirected graph class that can store multiedges.

o Multiedges are multiple edges between two nodes. Each edge can hold optional data or attributes.

o A MultiGraph holds undirected edges. Self loops are allowed.

o Nodes can be arbitrary (hashable) Python objects with optional key/value attributes.

o Edges are represented as links between nodes with optional key/value attributes.

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

V a set of vertices or nodes,

A a multiset of ordered pairs of vertices called directed edges, arcs or arrow