You are on page 1of 12

February 2010

Master of Computer Application (MCA) –


Semester 2
MC0068 – Data Structures using C
Assignment Set – 1

1. Write a program in C using one dimensional arrays


to sort a given list of n numbers using any of the
sorting techniques.
Ans –

#include<conio.h>
#include<stdio.h>

void main()
{ int i,j,a[10],n,temp;
clrscr();
scanf("NO. of elements: %d ",&n);
for (i=0;i<n;i++) scanf(“%d”,&a[i]);
clrscr();
printf("You array...\n");
for (i=0;i<n;i++) printf(&a[i]," ");
for (i=0;i<n;i++)
{ for (j=0;j<(n-1)-i;j++)
if (a[j]>a[j+1])
{ temp=a[j];
a[j]=a[j+1];
a[j+1]=temp;
}
}
printf("\n\nSorted Array...\n");
for (i=0;i<n;i++) cout<<a[i]<<" ";
getch();
}
2. Demonstrate with your own programming example
the usage of structures within an array.
Ans –
#include<conio.h>
#include<stdio.h>

void main()
{ struct student
{ int roll;
Char name[20];
}
} std[5]; //declaring an array of structure

For (int i=0;i<5;i++)


{ scanf(“enter roll no: %d”,&std[i].roll);
Scanf(“enter name: %c”,&std[i].name);
}
}

3. Explain the theory of non linear data structures.


Ans –

Trees

we consider one of the most Important non-linear Information


structures- trees. A tree Is often used to represent a hierarchy. This is
because the relationships between the Items In the hierarchy suggest
the branches of a botanical tree.

For example, a tree-like organization charts often used to


represent the lines of responsibility in a business as shown in Figure. The
president of the company is shown at the top of the tree and the vice-
presidents are indicated below her. Under the vice-presidents we find the
managers and below the managers the rest of the clerks. Each clerk
reports to a manager. Each manager reports to a vice-president, and
each vice-president reports to the president.
It just takes a little imagination to see the tree in Figure. Of course.
The tree is upside-down. However, this is the usual way the data
structure is drawn. The president is called the root of the tree and the
clerks are the leaves.

A tree is extremely useful for certain kinds of computations. For


example. Suppose we wish to determine the total salaries paid to
employees by division or by department. The total of the salaries in
division A can be found by computing the sum of the salaries paid in
departments Al and A2 plus the salary of the vice-president of division A.
Similarly. The total of the salaries paid in department Al is the sum of the
salaries of the manager of department Al and of the two clerks below
her.

Clearly, in order to compute all the totals. It is necessary to


consider the salary of every employee. Therefore, an implementation of
this computation must visit all the employees in the tree. An algorithm
that systematically visits all the items in a tree is called a tree traversal.

In the same chapter we consider several different kinds of trees as


well as several different tree traversal algorithms. In addition. We show
how trees can be used to represent arithmetic expressions and how we
can evaluate an arithmetic expression by doing a tree traversal. The
following is a mathematical definition of a tree:

Definition (Tree) A tree T is a finite. Non-empty set of nodes ,

T = {r} U TI, U T2 U …U Tn with the following properties:

3. A designated node of the set, r, is called the root of the tree: and

4. The remaining nodes are partitioned into n≥ O subsets T, T. …Tn each


of which is a tree for convenience, we shall use the notation T= {r. T, T,
…T} denote the tree T.

Notice that Definition is recursive-a tree is defined in terms of itself!


Fortunately, we do not have a problem with infinite recursion because
every tree has a finite number of nodes and because in the base case a
tree has n=0 subtrees.

It follows from Definition that the minimal tree is a tree comprised of a


single root node. For example Ta = {A}.
Finally. The following Tb = {B, {C}} is also a tree

Ta = {D, {E. {F}}, {G.{H,II}}, {J, {K}. {L}}, {M}}}

How do Ta Tb. & Tc resemble their arboreal namesake? The


similarity becomes apparent when we consider the graphical
representation of these trees shown in Figure. To draw such a pictorial
representation of a tree, T = {r. T1 ,T2, …Tn, beside each other below the
root. Finally, lines are drawn from rto the roots of each of the subtrees.
T1T2…….Tn

Figure : Examples of trees.

Of course, trees drawn in this fashion are upside down.


Nevertheless, this is the conventional way in which tree data structures
are drawn. In fact, it is understood that when we speak of “up” and
“down,” we do so with respect to this pictorial representation. For
example, when we move from a root to a subtree, we will say that we are
moving down the tree.

The inverted pictorial representation of trees is probably due to the


way that genealogical lineal charts are drawn. A lineal chart is a family
tree that shows the descendants of some person. And it is from
genealogy that much of the terminology associated with tree data
structures is taken.

Figure shows one representation of the tree Tc defined in Equation.


In this case, the tree is represented as a set of nested regions in the
plane. In fact, what we have is a Venn diagram which corresponds to the
view that a tree is a set of sets.

Figure: An alternate graphical representation for trees.

Binary Tree
Used to implement lists whose elements have a natural order (e.g.
numbers) and either (a) the application would like the list kept in this
order or (b) the order of elements is irrelevant to the application (e.g.
this list is implementing a set).

Each element in a binary tree is stored in a "node" class (or struct).


Each node contains pointers to a left child node and a right child node. In
some implementations, it may also contain a pointer to the parent node.
A tree may also have an object of a second "tree" class (or struct) which
as a header for the tree. The "tree" object contains a pointer to the root
of the tree (the node with no parent) and whatever other information the
programmer wants to squirrel away in it (e.g. number of nodes currently
in the tree).

In a binary tree, elements are kept sorted in left to right order


across the tree. That is if N is a node, then the value stored in N must be
larger than the value stored in left-child(N) and less than the value
stored in right-child(N). Variant trees may have the opposite order
(smaller values to the right rather than to the left) or may allow two
different nodes to contain equal values.

Hash Tables

A very common paradigm in data processing involves storing


information in a table and then later retrieving the information stored
there. For example, consider a database of driver’s license records. The
database contains one record for each driver’s license issued. Given a
driver’s license number. we can look up the information associated with
that number. Similar operations are done by the C compiler. The
compiler uses a symbol table to keep track of the user-defined symbols
in a Java program. As it compiles a program, the compiler inserts an
entry in the symbol table every time a new symbol is declared. In
addition, every time a symbol is used, the compiler looks up the
attributes associated with that symbol to see that it is being used
correctly.

Typically the database comprises a collection of key-and-value


pairs. Information is retrieved from the database by searching for a given
key. In the case of the driver’~ license database, the key is the driver’s
license number and in the case of the symbol table, the key is the name
of the symbol.

In general, an application may perform a large number of insertion


and/ or look-up operations. Occasionally it is also necessary to remove
items from the database. Because a large number of operations will be
done we want to do them as quickly as possible.
Hash tables are a very practical way to maintain a dictionary. As
with bucket sort, it assumes we know that the distribution of keys is
fairly well-behaved.

Once you have its index. A hash function is a mathematical


function which maps keys to integers.

In bucket sort, our hash function mapped the key to a bucket


based on the first letters of the key. "Collisions" were the set of keys
mapped to the same bucket. If the keys were uniformly distributed. then
each bucket contains very few keys!

The resulting short lists were easily sorted, and could just as easily be
searched

We examine data structures which are designed specifically with


the objective of providing efficient insertion and find operations. In order
to meet the design objective certain concessions are made. Specifically,
we do not require that there be any specific ordering of the items in the
container. In addition, while we still require the ability to remove items
from the container, it is not our primary objective to make removal as
efficient as the insertion and find operations.

Ideally we would’ build a data structure for which both the insertion
and find operations are 0(1) in the worst case. However, this kind of
performance can only be achieved with complete a priori knowledge. We
need to know beforehand specifically which items are to be inserted into
the container. Unfortunately, we do not have this information in the
general case. So, if we cannot guarantee 0(1) performance in the worst
case, then we make it our design objective to achieve 0(1) performance
in the average case.

The constant time performance objective immediately leads us to


the following conclusion: Our implementation must be based in some
way Kh element of an array in constant time, whereas the same
operation in a linked list takes O{k) time.

In the previous section, we consider two searchable containers-the


ordered list and the sorted list. In the case of an ordered list, the cost of
an insertion is 0(1) and the cost of the find operation is O(n). For a sorted
list the cost of insertion is O(n) and the cost of the find operation is O(log
n) for the array implementation.

Clearly, neither the ordered list nor the sorted list meets our
performance objectives. The essential problem is that a search, either
linear or binary, is always necessary. In the ordered list, the find
operation uses a linear search to locate the item. In the sorted list, a
binary search can be used to locate the item because the data is sorted.
However, in order to keep the data sorted, insertion becomes O(n).

In order to meet the performance objective of constant time insert


and find operations. we need a way to do them without performing a
search. That is, given an item x, we need to be able to determine directly
from x the array position where it is to be stored.

4. Write a program in C showing the implementation of


stack operations using arrays.
Ans –
#include<stdio.h>
#include<conio.h>
#define Max 5
int a [Max] , top=-l;-
void push()
{
int ele;
char ch;
if(top= =-l)
top=0;
do
{
if(top>=5)
{
printf("Stack if full");
break;
else
{
clrscr();
printf ( "Enter element to be insertedn" ) ;
scanf(“%d”,&ele);
a[top++] =ele;
}
printf ( "Do you want to add more elements: ?n") ;
scanf ( "n%c" , &ch);
printf(“%c”,ch)
}while((ch= = ‘Y’)||(ch==’Y’));
}
void pop( )
{
if(top= =-l)
{
printf ( "stack is underflown");
}
else
{
for(int i=top-l;i>=0;i–)
printf ("%dn", a [i] ) ;
}
}
void main()
{
clrscr ( ) ;
char c;
int choice;
do
{
clrscr( );
printf ("Enter Your Choicen");
printf("l -> Pushn");
printf ("2 -> Popn");
scanf ("%d", &Choice);
if(choice= =l)
push( );
else if (choice= = 2)
pop( );
else
printf(“invalid choice”);
printf(“Do You Want to continuen”);
scanf(“n%c”,&c);
}while((c= = ‘y’)||(c= = ‘Y’));
}

5. Write the code blocks in C to perform the following


operations on Circular Linked lists:
A) Insertion of a node at the front
B) Deletion of a node at the front

Ans –

A) Insertion of a node at the front end

NODE insert_ front (int item, NODE last)


{
NODE temp;
temp = getnode( ); /* Create a new node to be inserted */
temp->info = item;
if (last = = NULL) /* Make temp as the first node */
last = temp;
else /* Insert at the front end */
temp->link = last->link;
last->link = temp; /* link last node to first node */
return last; /* Return the last node */
}

B) Deletion of a node at the front end

NODE delete_ front(NODE last)


{
NODE temp, first;
if ( last = = NULL )
{
printf("List is emptyn");
return NULL;
}
if ( last->link = = last) /* Only one node is present */
{
printf("The item deleted is %dn", last->info);
freenode (last);
return NULL;
}
/* List contains more than one node */
first = last->link; /* obtain node to be deleted */
last->link = last->link; /*Store new first node in link of last */
printf ("The item deleted is %dn", first->info);
freenode (first); /* delete the old first node */
return last;
}
6. With the help of a suitable numerical example,
explain the inorder, preorder and postorder traversals
on a Binary Search Tree.
Ans –

With the linear, contiguous ordering of an array’s elements,


iterating through an array is a straightforward manner: start at the first
array element, and step through each element sequentially. For BSTs
there are three different kinds of traversals that are commonly used:

· Preorder traversal

· Inorder traversal

· Postorder traversal

Essentially, all three traversals work in roughly the same manner.


They start at the root and visit that node and its children. The difference
among these three traversal methods is the order with which they visit
the node itself versus visiting its children.

Preorder Traversal
Preorder traversal starts by visiting the current node – call it c,
then its left child, and then its right child. Starting with the BST’s root as
c, this algorithm can be written out as:

Step 1: Visit c. This might mean printing out the value of the node,
adding the node to a List, or something else. It depends on what you
want to accomplish by traversing the BST.

Step 2: Repeat step 1 using c’s left child.

Step 3: Repeat step 1 using c’s right child.

Imagine that in step 1 of the algorithm we were printing out the


value of c. In this case, what would the output be for a preorder traversal
of the BST in Figure 1.8? Well, starting with step 1 we would print the
root’s value. Step 2 would have us repeat step 1 with the root’s left child,
so we’d print 50. Step 2 would have us repeat step 1 with the root’s left
child’s left child, so we’d print 20. This would repeat all the way down the
left side of the tree. When 5 were reached, we’d first print out its value
(step 1). Since there are no left or right children of 5, we’d return to node
20, and perform its step 3, which is repeating step 1 with 20’s right child,
or 25. Since 25 has no children, we’d return to 20, but we’ve done all
three steps for 20, so we’d return to 50, and then take on step 3 for node
50, which is repeating step 1 for node 50’s right child. This process would
continue on until each node in the BST had been visited.

Inorder Traversal

Inorder traversal starts by visiting the current node’s left child,


then the current node, and then its right child. Starting with the BST’s
root as c, this algorithm can be written out as:

Step 1: Repeat step 1 using c’s left child.

Step 2: Visit c. This might mean printing out the value of the node,
adding the node to an ArrayList, or something else. It depends on what
you want to accomplish by traversing the BST.

Step 3: Repeat step 1 using c’s right child.

Postorder Traversal

Finally, postorder traversal starts by visiting the current node’s left


child, then its right child, and finally the current node itself. Starting with
the BST’s root as c, this algorithm can be written out as:

Step 1: Repeat step 1 using c’s left child.

Step 2: Repeat step 1 using c’s right child.


Step 3: Visit c.

This might mean printing out the value of the node, adding the
node to an ArrayList, or something else. It depends on what you want to
accomplish by traversing the BST.

Realize that all three traversal times exhibit linear asymptotic


running time. This is because each traversal option visits each and every
node in the BST precisely once. So, if the numbers of nodes in the BST
are doubled, the amount of work for a traversal doubles as well.

7. Explain the theory of Minimum spanning trees.


Ans –

Tree is one of the most efficient data structure used in a computer


program. There are many types of tree. Binary tree is a tree that always
have two branches, Red-Black-Trees, 2-3-4 Trees, AVL Trees, etc. A well
balanced tree can be used to design a good searching algorithm.

A Tree is an undirected graph that contains no cycles and is


connected. Many trees are what is called rooted, where there is a notion
of the "top" node, which is called the root. Thus, each node has one
parent, which is the adjacent node which is closer to the root, and may
have any number of children, which are the rest of the nodes adjacent to
it. The tree above was drawn as a rooted tree.

Spanning trees

A spanning tree of a graph is just a subgraph that contains all the


vertices and is a tree. A graph may have many spanning trees; for
instance the complete graph on four vertices

Minimum spanning trees

Now suppose the edges of the graph have weights or lengths. The
weight of a tree is just the sum of weights of its edges. Obviously,
different trees have different lengths. The problem: how to find the
minimum length spanning tree?

The standard application is to a problem like phone network


design. You have a business with several offices; you want to lease
phone lines to connect them up with each other; and the phone company
charges different amounts of money to connect different pairs of cities.
You want a set of lines that connects all your offices with a minimum
total cost. It should be a spanning tree, since if a network isn’t a tree you
can always remove some edges and save money.
A less obvious application is that the minimum spanning tree can
be used to approximately solve the traveling salesman problem. A
convenient formal way of defining this problem is to find the shortest
path that visits each point at least once. Note that if you have a path
visiting all points exactly once, it’s a special kind of tree. For instance, in
the example above, twelve of sixteen spanning trees are actually paths.
If you have a path visiting some vertices more than once, you can always
drop some edges to get a tree. So in general the MST weight is less than
the TSP weight, because it’s a minimization over a strictly larger set.

On the other hand, if you draw a path tracing around the minimum
spanning tree, you trace each edge twice and visit all points, so the TSP
weight is less than twice the MST weight. Therefore this tour is within a
factor of two of optimal.

8. Explain the following graph problems:


A) Telecommunication problem
B) Knight Moves
Ans –

Telecommunication problem

Given a set of computers and a set of wires running between pairs


of computers, what is the minimum number of machines whose crash
causes two given machines to be unable to communicate? (The two
given machines will not crash.)

Graph: The vertices of the graph are the computers. The edges are
the wires between the computers. Graph problem: minimum dominating
sub-graph.

Knight moves

Given: Two squares on an 8×8 chessboard. Determine the shortest


sequence of knight moves from one square to the other.

Graph: The graph here is harder to see. Each location on the


chessboard represents a vertex. There is an edge between two positions
if it is a legal knight move. Graph Problem: Single Source Shortest Path.

You might also like