0% found this document useful (0 votes)
61 views15 pages

Discuss The Roll of Stack in Case of Recursion With Help of A Suitable Example

The stack is used in recursion to store information about each recursive call. When a recursive function calls itself, space is allocated on the stack to store information for that recursive call. When the call returns, the information is removed from the stack. This continues each time a recursive call is made, with new information added and old information removed, allowing recursive functions to call themselves repeatedly. Queues are commonly used in operating systems to manage processes, in simulations to model real-world waiting lines, and to implement print queues and call waiting systems. They ensure requests are processed in the order received. Almost complete binary trees require every node with a right child to also have a left child, while complete binary trees require every level except the

Uploaded by

jasmine_6
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOC, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
61 views15 pages

Discuss The Roll of Stack in Case of Recursion With Help of A Suitable Example

The stack is used in recursion to store information about each recursive call. When a recursive function calls itself, space is allocated on the stack to store information for that recursive call. When the call returns, the information is removed from the stack. This continues each time a recursive call is made, with new information added and old information removed, allowing recursive functions to call themselves repeatedly. Queues are commonly used in operating systems to manage processes, in simulations to model real-world waiting lines, and to implement print queues and call waiting systems. They ensure requests are processed in the order received. Almost complete binary trees require every node with a right child to also have a left child, while complete binary trees require every level except the

Uploaded by

jasmine_6
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOC, PDF, TXT or read online on Scribd
You are on page 1/ 15

1)Discuss the roll of stack in case of Recursion with help of a suitable

example.

Ans:The following program includes a call to the recursively defined function


"print_backwards()", which inputs a series of characters from the keyboard,
terminated with a full-stop character, and then prints them backwards on the screen.

#include<iostream>
using namespace std;
void print_backwards();
int main()
{
print_backwards();
cout << "\n";
return 0;
}
void print_backwards()
{
char character;
cout << "Enter a character ('.' to end program): ";
cin >> character;
if (character != '.')
{
print_backwards();
cout << character;
}
}

A typical input/output session is:

Enter a character ('.' to end program): H


Enter a character ('.' to end program): i
Enter a character ('.' to end program): .iH

We will examine how this function works in more detail in the next section. But
notice that the recursive call to "print_backwards()" (within its own definition) is
embedded in an "if" statement. In general, recursive definitions must always use some
sort of branch statement with at least one non-recursive branch, which acts as the base
case of the definition. Otherwise they will "loop forever". In above Program the base
case is in the implicit "else" part of the "if" statement. We could have written the
function as follows:

void print_backwards()
{
char character;

cout << "Enter a character ('.' to end program): ";


cin >> character;
if (character != '.')
{
print_backwards();
cout << character;
}
else
}
The Mechanics of a Recursive Call

It is easy to see why works with the above aid of a few diagrams. When the main
program executes, it begins with a call to "print_backwards()". At this point space is
set aside in the computer's memory to execute this call (and in other cases in which to
make copies of the value parameters). This space is represented as a box in following
figure

The internal execution of this call begins with a character input, and then a second call
to "print_backwards()" (at this point, nothing has been output to the screen). Again,
space is set aside for this second call:
The process repeats, but inside the third call to "print_backwards()" a full-stop
character is input, thus allowing the third call to terminate with no further function
calls:

This allows the second call to "print_backwards()" to terminate by outputting an "i"


character, which in turn allows the first call to terminate by outputting an "H"
character:

Technically speaking, C++ arranges the memory spaces needed for each function call
in a stack. The memory area for each new call is placed on the top of the stack, and
then taken off again when the execution of the call is completed. In the example
above, the stack goes through the following sequence:
C++ uses this stacking principle for all nested function calls - not just for recursively
defined functions. A stack is an example of a "last in/first out" structure (as opposed
to, for example, a queue, which is a "first in/first out" structure).

2).Discuss the various applications where the Queues are applied, also give the
justification for those applications.

Ans:typical uses of queues are in simulations and operating systems.

• Operating systems often maintain a queue of processes that are ready to


execute or that are waiting for a particular event to occur.
• Computer systems must often provide a “holding area” for messages between
two processes, two programs, or even two systems. This holding area is
usually called a “buffer” and is often implemented as a queue.
• on the situation where there are multiple users or a networked computer
system, you probably share a printer with other users. When you request to
print a file, your request is added to the print queue. When your request
reaches the front of the print queue, your file is printed. This ensures that only
one person at a time has access to the printer and that this access is given on a
first-come, first-served basis.
• For simulation of real-world situations. For instance, a new bank may want to
know how many tellers to install. The goal is to service each customer within
a "reasonable" wait time, but not have too many tellers for the number of
customers. To find out a good number of tellers, they can run a computer
simulation of typical customer transactions using queues to represent the
waiting customers.
• When placed on hold for telephone operators. For example, when you phone
the toll-free number for your bank, you may get a recording that says, "Thank
you for calling A-1 Bank. Your call will be answered by the next available
operator. Please wait." This is a queuing system.
• Destination queues—any queue that the sending application sends messages to
or that the receiving application reads messages from.destination queues are
any application queue that is used to store messages sent from an application.
Typically, the destination queue is a local queue on a server. Client
applications send messages to the destination queue on the server computer (in
this case the server computer can also be referred to as the target computer),
and the server applications process the messages after they arrive.The
following illustration shows a single destination queue used by two
applications. The sending application on the client computer sends the
message to the queue and the receiving application on the server computer
reads the messages from the queue. Typically, destination queues are located
on the same computer as the receiving application in order to minimize
network traffic.

Destination queues can be public or private, and they can


be transactional or nontransactional. When designing a distributed Message Queuing
application, you must decide if the destination queues should be public or private
queues, and whether the public or private queues used should be transactional or
nontransactional. Whether a queue is public, private, transactional, or
nontransactional is specified when the queue is created.

• Administration queues—queues used for acknowledgment messages returned by


Message Queuing or connector applications. Administration queues are
application queues used to store system-generated negative and positive
acknowledgment messages that are created by Message Queuing or connector
applications. Any available nontransactional queue can be used as an
administration queue.The system-generated acknowledgment messages returned
to these queues can indicate whether a message arrived at its destination queue,
whether it was retrieved from the destination queue, or both. Each
acknowledgment message contains information that describes what triggered the
acknowledgment and to which message the acknowledgment refers.When
requesting acknowledgment messages, the sending application must specify the
queue to be used as the administration queue and the acknowledgment levelof the
message. Typically, an administration queue should be a local queue so that the
sending application can read the acknowledgment messages locally.
• Response queues—queues used by receiving applications to return response
messages to the sending application. Response queues are application queues used
to store application-generated response messages that are typically returned by an
application that is reading messages from a queue. Any available queue can be
specified as a response queue.The response messages returned to these queues
must be understood by the application returning the response messages and the
application reading the response message. Message Queuing has no control over
what information is sent in response messages.When requesting response
messages, the sending application must specify the queues that it wants to use as
response queues. Typically, response queues should be local queues so that the
sending application can read the response messages locally.
• Report queues—queues used to store report messages returned by Message
Queuing. Report queues are public queues used to store report messages
generated by Message Queuing or connector applications when route tracking
is enabled on the source computer by the Message Queuing administrator and
tracing is requested for messages by the sending application. When a message
is sent with tracing requested from a computer with route tracking enabled, a
report message is generated each time the message leaves or arrives at a
Message Queuing computer, including a Message Queuing routing server.

3)Differentiate between Almost binary tree and complete binary Trees.

Ans:An almost complete binary tree is a tree in which each node that has a right
child also has a left child. Having a left child does not require a node to have a right
child. Stated alternately, an almost complete binary tree is a tree where for a right
child, there is always a left child, but for a left child there may not be a right child.
The number of nodes in a binary tree can be found using this formula: n = 2^h Where
n is the amount of nodes in the tree, and h is the height of the tree.

Diagram: An almost complete binary tree

An almost complete strictly binary tree with N leaves has 2N – 1 nodes (as does any
other strictly binary tree). An almost complete binary tree with N leaves that is not
strictly binary has 2N nodes. There are two distinct almost complete binary trees
with N leaves, one of which is strictly binary and one of which is not.

There is only a single almost complete binary tree with N nodes. This tree is strictly
binary if and only if N is odd.
A complete binary tree of depth d is the strictly binary tree all of whose leaves are at
level d.

The total number of nodes in a complete binary tree of depth d equals 2d+1 – 1. Since
all leaves in such a tree are at level d, the tree contains 2d leaves and, therefore, 2d - 1
internal nodes.

Diagram : A complete binary tree

A binary tree of depth d is an almost complete binary tree if:

• Each leaf in the tree is either at level d or at level d – 1.


• For any node nd in the tree with a right descendant at level d, all the left
descendants of nd that are leaves are also at level d.

A complete binary tree may also be defined as a full binary tree in which all
leaves are at depth n or n-1 for some n. In order for a tree to be the latter kind
of complete binary tree, all the children on the last level must occupy the
leftmost spots consecutively, with no spot left unoccupied in between any two.
For example, if two nodes on the bottommost level each occupy a spot with an
empty spot between the two of them, but the rest of the children nodes are
tightly wedged together with no spots in between, then the tree cannot be a
complete binary tree due to the empty spot.

4.The following is the adjacency matrix .A=

0 1 0 1 0
1 0 0 1 1
0 0 0 1 1
1 1 1 0 1
0 1 1 10

Draw the graph G.

Ans:
A

B D

C E
Part-b

1. Differentiate Max Heap and Min Heap and sort the following using
heap sort.

D,A,T,A,S,T,R,U,C,T,U,R,E,S.

T
D D

A T A D
A

T
T U
T

S T S
R
A D S D
A C A T
D E R

A A
A S
Given a set S of values, a min-max heap on S is a
binary tree T with the following properties:
1) T has the heap-shape
2) T is min-max ordered: values stored at nodes on even (odd) levels are
smaller (greater) than or equal to the values stored at their descendants
(if any) where the root is at level zero. Thus, the smallest value of S is
stored at the root of T, whereas the largest value is stored at one of the
root’s children; an example of a min-max heap is shown in Figure 1
(p. 998). A min-max heap on n elements can be stored in an array A[1 .
. . n]. The ith location in the array will correspond to a node located on
level L(log,i)l in the heap. A max-min heap is defined analogously; in
such a heap, the maximum value is stored at the root, and the smallest
value is stored at one of the root’s children. It is interesting to observe
that the Hasse diagram for a min-max heap (i.e., the diagram representing
the order relationships implicit within the structure) is rather complex in
contrast with the one for a traditional heap (in this case, the Hasse
diagram is the heap itself); Figure 2 (p. 998) shows the Hasse
diagram for the example of Figure 1. Algorithms processing min-max
heaps are very similar to those corresponding to conventional heaps.
Creating a min-max heap is accomplished by an adaption of Floyd’s [4]
linear-time heap construction algorithm. Floyd’s algorithm builds a heap
in a new element is placed into the next available leaf position, and
must then move up the diagram toward the top, or down toward the
bottom, to ensure that all paths running from top to bottom remain
sorted. Thus the algorithm must first determine whether the new element
should proceed further down the Hasse diagram (i.e., up the heap on
max- levels) or up the Hasse diagram (i.e., up the heap on successive
min-levels). Once this has been determined, only grandparents along the
path to the root of the heap need be examined-either those lying on min-
levels or those lying on max-levels.

2.Give the description of some of the applications that require the usage
of the Heap data structure than the Tree.

Ans:Priority Queues: Priority queues can be efficiently implemented using


Binary Heap because it supports insert(), delete() and extractmax(),
decreaseKey() operations in O(logn) time. Binomoial Heap and Fibonacci
Heap are variations of Binary Heap. These variations perform union also in
O(logn) time which is a O(n) operation in Binary Heap. Heap Implemented
priority queues are used in Graph algorithms like Prim’s
Algorithm and Dijkstra’s algorithm.

 Order statistics: The Heap data structure can be used to efficiently find the kth
sm Heapsort: One of the best sorting methods being in-place and with no
quadratic worst-case scenarios.
 Selection algorithms: Finding the min, max, both the min and max, median, or
even the k-th largest element can be done in linear time (often constant time)
using heaps.[4]
 Graph algorithms: By using heaps as internal traversal data structures, run
time will be reduced by polynomial order. Examples of such problems are Prim's
minimal spanning tree algorithm and Dijkstra's shortest path problem.

Full and almost full binary heaps may be represented in a very space-efficient way
using an array alone. The first (or last) element will contain the root. The next two
elements of the array contain its children. The next four contain the four children of
the two child nodes, etc. Thus the children of the node at position n would be at
positions 2n and 2n+1 in a one-based array, or 2n+1 and 2n+2 in a zero-based array.
This allows moving up or down the tree by doing simple index computations.
Balancing a heap is done by swapping elements which are out of order. As we can
build a heap from an array without requiring extra memory (for the nodes, for
example), heapsort can be used to sort an array in-place.

One more advantage of heaps over trees in some applications is that construction of
heaps can be done in linear time using Tarjan's algorithm
Applications: A heap has many applications, including the most efficient implementation of priority queu

Variants:

• 2-3 heap
• Binary heap
• Many many others

Binary heap storage rules -- A heap implemented with a binary tree in which the following two rules ar

• The element contained by each node is greater than or equal to the elements of that node's children
• The tree is a complete binary tree.

Example: which one is a heap?


Heap Implementation
Adding an Element to a Heap

Example: We want to insert a node with value 42 to the heap on the left.

The above process is called reheapification upward.

Pseudocode for Adding an Element:

1. Place the new element in the heap in the first available location. This keeps the structure as a comp
2. while (the new element has a greater value than its parent) swap the new element with its parent.
3. Notice that Step 2 will stop when the new element reaches the root or when the new element's pare

Removing the Root of a Heap

The procedure for deleting the root from the heap -- effectively extracting the maximum element in a max
The above process is called reheapification downward.

Psuedocode for Removing the Root:

1. Copy the element at the root of the heap to the variable used to return a value.
2. Copy the last element in the deepest level to the root and then take this last node out of the tree. Th
3. while (the out-of-place element has a value that is lower than one of its children) swap the out-of-p
4. Return the answer that was saved in Step 1.
5. Notice that Step 3 will stop when the out-of-place element reaches a leaf or it has a value that is gr

Now, think about how to build a heap. Check out the example of inserting 27, 35, 23, 22, 4, 45, 21, 5, 42 a

Heap Implementation
It is perfectly acceptable to use a traditional binary tree data structure to implement a binary heap. There i

A more common approach is to store the heap in an array. Since heap is always a complete binary tree, it
array indices.

The rules (assume the root is stored in arr[0]):

• For each index i, element arr[i] has children at arr[2i + 1] and arr[2i + 2], and the parent at arr[floo

This implementation is particularly useful in the heapsort algorithm, where it allows the space in the input
method not that useful in priority queues implementation, where the number of elements is unknown.

Building a Heap
A heap could be built by successive insertions. This approach requires O(n log n) time for n elements. Wh

The optimal method:

• Starts by arbitrarily putting the elements on a binary tree.


• Starting from the lowest level and moving upwards until the heap property is restored by shifting t
• If all the subtrees at some height h (measured from the bottom) have already been "heapified", the

As an example, let's build a heap with the following values: 20, 35, 23, 22, 4, 45, 21, 5, 42 and 19. Click h

As has been proved here, this optimal method requires O(n) time for n elements.

Priority Queues
A priority queue behaves much like an ordinary queue:

• Elements are placed in the queue and later taken out.


• But each element in a priority queue has an associated number called its priority.
• When elements leave a priority queue, the highest priority element always leaves first.

Heap Implementation of P.Q.

In the heap implementation of a priority queue, each node of the heap contains one element along with the

• The element contained by each node has a priority that is greater than or equal to the priorities of t
• The tree is a complete binary tree.

A P.Q. Implementation Using an Ordinary Queue

• Define an array of ordinary queues, called queues[].


• The items with priority 0 are stored in queues[0]. Items with priority 1 are stored in queues[1]. An
• When an item with priority i needs to be added, we insert it to the end of queues[i].
• When an item needs to be removed, we move down through the ordinary queues, starting with the
variable to remember the current highest priority.

2. Write a program which prints the nodes of T in preorder and postooder.


#include <stdio.h>
#include <iostream.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;
};
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);

void printPostorder(struct node* node)


{
if (node == NULL)
return;
cout<<”Postorder(node->left)”;

cout<<”Postorder(node->right)”;

cout<<"\n”, node->data);
}
void printInorder(struct node* node)
{
if (node == NULL)
return;
printInorder(node->left);
cout<<(node->data);
printInorder(node->right);
}

void printPreorder(struct node* node)


{
if (node == NULL)
return;

cout<<(node->data);

printPreorder(node->left);

printPreorder(node->right);
}

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);

cout<<("\n Preorder traversal of binary tree is \n");


printPreorder(root);

cout<<("\n Inorder traversal of binary tree is \n");


printInorder(root);

cout<<"\n Postorder traversal of binary tree is \n");


printPostorder(root);
.
getchar();
return 0;
}
5.Write a procedure to find the shortest path from a given node A to a given
node B.
Ans: First Shortest-Path Algorithm
STEP 1 To initialize the process set d(s) = O. p(s) = *; set d(j) = , p(j) =
-for all other nodes j s; consider node s as closed and all other
nodes as open; set k = s (i.e., s is the last closed node).
STEP 2 To update the labels, examine all edges (k, j) out of the last closed
node; if node j is closed, go to the next edge; if node j is open, set the
first entry of its label to

d(j) = Min [d(j), d(k) + (k,i)] (6.1)


STEP 3 To choose the next node to close, compare the d(j) parts of the labels
for all nodes that are in the open state. Choose the node with the
smallest d(j) as the next node to be closed. Suppose that this is node
i.
STEP 4 To find the predecessor node of the next node to be closed, i,
consider, one at a time, the edges (j, i) leading from closed nodes to i
until one is found such that

d(i) - {(a, i) = d(j)

Let this predecessor node be j*. Then set p(i) = j*.


STEP 5 Now consider node i as a closed node. If all nodes in the graph are
closed, then stop; the procedure is finished. If there are still some
open nodes in the graph, set k = i and return to Step 2.

Upon termination of the algorithm, the d(j) part of the label of node j
indicates the length of the shortest path from s to j, while thep(j) part
indicates the predecessor node to j on this shortest path. By tracing
back the pa j) parts, it is easy to identify the shortest paths between s
and each of the nodes of G.

You might also like