Sie sind auf Seite 1von 22

Assignment No.

Name: Fawad Ahmad


Roll no:BW503013

Course Name: Data Structures


Course Code: 3581
Semester: Autumn 2019
Level: PGD (CS)
Question 1 Part (A)

A data structure is a specialized format for organizing and storing data. Differentiate between
physical and logical data structure. Give examples to support your

Answer:

What is Data Structure?


In computer science, a data structure is a data organization, management, and storage format that enables
efficient access and modification. More precisely, a data structure is a collection of data values, the
relationships among them, and the functions or operations that can be applied to the data.
Key differences between physical and logical data structure?
When data structures are first defined, only the data elements that the user would see, such as a name,
address, and balance due, are included. This stage is the logical design, showing what data the business
needs for its day-to-day operations. As we learned from HCI, it is important that the logical design
accurately reflect the mental model of how the user views the system. Using the logical design as a basis,
the analyst then designs the physical data structures, which include additional elements necessary for
implementing the system. Examples of physical design elements are the following:

 Key fields used to locate records in a database table. An example is an item number, which is not
required for a business to function but is necessary for identifying and locating computer records.
 Codes to identify the status of master records, such as whether an employee is active (currently
employed) or inactive. Such codes can be maintained on files that produce tax information.
 Transaction codes are used to identify types of records when a file contains different record types.
An example is a credit file containing records for returned items as well as records of payments.
 Repeating group entries containing a count of how many items are in the group.
 Limits on the number of items in a repeated group.
 A password used by a customer accessing a secure Web site.
Uses of Data Structure:
Data structures serve as the basis for abstract data types (ADT). The ADT defines the logical form of the
data type. The data structure implements the physical form of the data type. Different types of data
structures are suited to different kinds of applications, and some are highly specialized to specific tasks. For
example, relational databases commonly use B-tree indexes for data retrieval, while compiler
implementations usually use hash tables to look up identifiers.
Data structures provide a means to manage large amounts of data efficiently for uses such as large databases
and internet indexing services. Usually, efficient data structures are key to designing efficient algorithms.
Some formal design methods and programming languages emphasize data structures, rather than
algorithms, as the key organizing factor in software design. Data structures can be used to organize the
storage and retrieval of information stored in both main memory and secondary memory.
Example:
Figure illustrated below is an example of the data structure for a CUSTOMER BILLING STATEMENT,
one showing that the ORDER LINE is both a repeating item and a structural record. The ORDER LINE
limits are from 1 to 5, indicating that the customer may order from one to five items on this screen.
Additional items would appear on subsequent orders.
Physical elements added to a data structure. The repeating group notation may have several other formats.
If the group repeats a fixed number of times, that number is placed next to the opening brace, as in 12
{Monthly Sales}, where there are always 12 months in the year. If no number is indicated, the group repeats
indefinitely. An example is a table containing an indefinite number of records, such as Customer Master
Table {Customer Records}. The number of entries in repeating groups may also depend on a condition,
such as an entry on the Customer Master Record for each item ordered. This condition could be stored in
the data dictionary as {Items Purchased} 5, where 5 is the number of items.

Question 1 Part (B)

An algorithm is a step by step method of solving a problem. It is commonly used for data
processing, calculations and other related computer and mathematical operations. Explain the
criteria that is considered while choosing an appropriate algorithm to solve a particular problem.

Answer:

What is Algorithm?
The word Algorithm means “a process or set of rules to be followed in calculations or other problem-solving
operations”. Therefore Algorithm refers to a set of rules/instructions that step-by-step define how a work is
to be executed upon in order to get the expected results.
It can be understood by taking an example of cooking a new recipe. To cook a new recipe, one reads the
instructions and steps and execute them one by one, in the given sequence. The result thus obtained is the
new dish cooked perfectly. Similarly, algorithms help to do a task in programming to get the expected
output.
The Algorithm designed are language-independent, i.e. they are just plain instructions that can be
implemented in any language, and yet the output will be the same, as expected.
Criteria for choosing algorithm?
To choose the appropriate algorithm for different data, you need to know some properties about your input
data. We created several benchmark data sets on which to show how the algorithms presented in this chapter
compare with one another. Note that the actual values of the generated tables are less important because
they reflect the specific hardware on which the benchmarks were run. Instead, you should pay attention to
the relative performance of the algorithms on the corresponding data sets:

 Random Strings:
Throughout this chapter, we have demonstrated performance of sorting algorithms when sorting
26-character strings that are permutations of the letters in the alphabet. Given there are n! such
strings, or roughly 4.03*1026 strings, there are few duplicate strings in our sample data sets. In
addition, the cost of comparing elements is not constant, because of the occasional need to compare
multiple characters.
 Double Precision floating point value
Using available pseudorandom generators available on most operating systems, we generate a set
of random numbers from the range (0,1). There are essentially no duplicate values in the sample
data set and the cost of comparing two elements is a fixed constant. The input data provided to the
sorting algorithms can be preprocessed to ensure some of the following properties not all are
compatible.
 Sorted:
The input elements can be presorted into ascending order (the ultimate goal) or in descending order.
 Killer median of three:
Musser (1997) discovered an ordering that ensures that Quicksort requires O(n2) comparisons
when using median-of-three to choose a pivot.
 Nearly Sorted:
Given a set of sorted data, we can select k pairs of elements to swap and the distance d with which
to swap (or 0 if any two pairs can be swapped). Using this capability, you can construct input sets
that might more closely match your input set. The upcoming tables are ordered left to right, based
upon how well the algorithms perform on the final row in the table.

Question 2 Part (A)

What are arrays and how they are represented in the memory? Elaborate the array representation
considering dingle and multi-dimensional arrays.

Answer:
What is Array?
In computer science, an array data structure, or simply an array, is a data structure consisting of a collection
of elements (values or variables), each identified by at least one array index or key. An array is stored such
that the position of each element can be computed from its index tuple by a mathematical formula. The
simplest type of data structure is a linear array, also called one-dimensional array
For example, an array of 10 32-bit (4 bytes) integer variables, with indices 0 through 9, may be stored as
10 words at memory addresses 2000, 2004, 2008, ... 2036, so that the element with index i has the address
2000 + (i × 4).
The memory address of the first element of an array is called first address, foundation address, or base
address. Because the mathematical concept of a matrix can be represented as a two-dimensional grid, two-
dimensional arrays are also sometimes called matrices. In some cases the term "vector" is used in computing
to refer to an array, although tuples rather than vectors are the more mathematically correct equivalent.
Tables are often implemented in the form of arrays, especially lookup tables; the word table is sometimes
used as a synonym of array.
Arrays are among the oldest and most important data structures, and are used by almost every program.
They are also used to implement many other data structures, such as lists and strings. They effectively
exploit the addressing logic of computers. In most modern computers and many external storage devices,
the memory is a one-dimensional array of words, whose indices are their addresses. Processors, especially
vector processors, are often optimized for array operations. Arrays are useful mostly because the element
indices can be computed at run time. Among other things, this feature allows a single iterative statement to
process arbitrarily many elements of an array. For that reason, the elements of an array data structure are
required to have the same size and should use the same data representation. The set of valid index tuples
and the addresses of the elements (and hence the element addressing formula) are usually, but not always,
fixed while the array is in use.
The term array is often used to mean array data type, a kind of data type provided by most high-level
programming languages that consists of a collection of values or variables that can be selected by one or
more indices computed at run-time. Array types are often implemented by array structures; however, in
some languages they may be implemented by hash tables, linked lists, search trees, or other data structures.
The term is also used, especially in the description of algorithms, to mean associative array or "abstract
array", a theoretical computer science model (an abstract data type or ADT) intended to capture the essential
properties of arrays.
What is One Dimensional Array?
A one-dimensional array (or single dimension array) is a type of linear array. Accessing its elements
involves a single subscript which can either represent a row or column index.
As an example consider the C declaration int an ArrayName
Syntax : datatype anArrayName[sizeofArray];
In the given example the array can contain 10 elements of any value available to the int type. In C, the array
element indices are 0-9 inclusive in this case. For example, the expressions an ArrayName and an
ArrayName are the first and last elements respectively.
For a vector with linear addressing, the element with index i is located at the address B + c × i, where B is
a fixed base address and c a fixed constant, sometimes called the address increment or stride. If the valid
element indices begin at 0, the constant B is simply the address of the first element of the array. For this
reason, the C programming language specifies that array indices always begin at 0; and many programmers
will call that element "zeroth" rather than "first".
However, one can choose the index of the first element by an appropriate choice of the base address B. For
example, if the array has five elements, indexed 1 through 5, and the base address B is replaced by B + 30c,
then the indices of those same elements will be 31 to 35. If the numbering does not start at 0, the constant
B may not be the address of any element.
What is Multi Dimensional Array?
For a multidimensional array, the element with indices i,j would have address B + c • i + d • j, where the
coefficients c and d are the row and column address increments, respectively.
More generally, in a k-dimensional array, the address of an element with indices i1, i2, ..., ik is
B + c1 • i1 + c2 • i2 + ... + ck • ik.
For example: int a[2][3];
This means that array a has 2 rows and 3 columns, and the array is of integer type. Here we can store 6
elements they will be stored linearly but starting from first row linear then continuing with second row. The
above array will be stored as a11, a12, a13, a21, a22, a23.
This formula requires only k multiplications and k additions, for any array that can fit in memory. Moreover,
if any coefficient is a fixed power of 2, the multiplication can be replaced by bit shifting. The coefficients
ck must be chosen so that every valid index tuple maps to the address of a distinct element. If the minimum
legal value for every index is 0, then B is the address of the element whose indices are all zero. As in the
one-dimensional case, the element indices may be changed by changing the base address B. Thus, if a two-
dimensional array has rows and columns indexed from 1 to 10 and 1 to 20, respectively, then replacing B
by B + c1 - − 3 c1 will cause them to be renumbered from 0 through 9 and 4 through 23, respectively.
Taking advantage of this feature, some languages (like FORTRAN 77) specify that array indices begin at
1, as in mathematical tradition while other languages (like Fortran 90, Pascal and Algol) let the user choose
the minimum value for each index.
How they are represented in memory?
Lets take an example
int a[5]; // Allocates memory for 5 ints.
...
a[0] = 1;
for (int i=1; i<5; i++) {
a[i] = a[i-1] * 2;
}
Arrays are often represented with diagrams that represent their memory use. The diagram below is one
typical way to represent the memory used by an array.
Each box represents the amount of memory needed to hold one array element. For ints this is usually 4
bytes. We can write the value of an element inside the box. Pointers hold the memory address of other data
and are represented by a black disk with an arrow pointing to the data it references.
The actual array variable, a in this example, is a pointer to the memory for all of its elements. A common
shortcut is to omit writing the array variable, and write only the elements that hold the data because these
are usually the focus of attention. Sometimes the cells are written horizontally, especially when showing
C-strings (arrays of characters).
Question 2 Part (B)

Consider a two-dimensional array arr[10][10] which has base address= 1000 and the number of
bytes per element of the array = 2. Now, compute the address of the element array[8][5] assuming
that the elements are stored in column major order.

Answer:
In case of Column Major Order:
The formula is:
LOC (A [J, K]) = Base (A) + w [M (K-1) + (J-1)]
Here
LOC (A [J, K]) : is the location of the element in the Jth row and Kth column.
Base (A) : is the base address of the array A.
w : is the number of bytes required to store single element of the array A.
M : is the total number of rows in the array.
J : is the row number of the element.
K : is the column number of the element.
A 3 x 4 integer array A is as below:

Subscript Elements Address


10 (1,1) 1000
20 (2,1) 1002
50 (3,1) 1004
60 (1,2) 1006
90 (2,2) 1008
40 (3,2) 1010
30 (1,3) 1012
80 (2,3) 1014
75 (3,3) 1016
55 (1,4) 1018
65 (2,4) 1020
79 (3,4) 1022
Suppose we have to find the location of A [3, 2].
The required values are:
Base (A) : 1000
w : 2 (because an integer takes 2
bytes in memory)
M : 3
J : 3
K : 2
Now put these values in the given formula as below:
LOC (A [3, 2]) = 1000 + 2 [3 (2-1) + (3-1)]
= 1000 + 2 [3 (1) + 2]
= 1000 + 2 [3 + 2]
= 1000 + 2 [5]
= 1000 + 10
= 1010

. In case of Row Major Order:

The formula is:


LOC (A [J, K]) = Base (A) + w [N (J-1) + (K-1)]
Here
LOC (A [J, K]) : is the location of the element in the Jth row and Kth column.
Base (A) : is the base address of the array A.
w : is the number of bytes required to store single element of the array A.
N : is the total number of columns in the array.
J : is the row number of the element.
K : is the column number of the element.

A 3 x 4 integer array A is as below:


Subscript Elements Address
10 (1,1) 1000
60 (1,2) 1002
30 (1,3) 1004
55 (1,4) 1006
20 (2,1) 1008
90 (2,2) 1010
80 (2,3) 1012
65 (2,4) 1014
50 (3,1) 1016
40 (3,2) 1018
75 (3,3) 1020
79 (3,4) 1022
Suppose we have to find the location of A [3, 2].
The required values are:
Base (A) : 1000
w : 2 (because an integer takes 2
bytes in memory)
N : 4
J : 3
K : 2
Now put these values in the given formula as below:
LOC (A [3, 2]) = 1000 + 2 [4 (3-1) + (2-1)]
= 1000 + 2 [4 (2) + 1]
= 1000 + 2 [8 + 1]
= 1000 + 2 [9]
= 1000 + 18
= 1018

Question 3 Part (A)

Consider an array MARKS[20][5] which stores the marks obtained by 20 students in 5 subjects.
Now write an algorithm to
(a) Find the average marks obtained in each subject
(b) Find the average marks obtained by every student
(c) Find the number of students who have scored below 50 in their average.
(d) Display the scores obtained by every student.

Implement the algorithm in any programming language (as specified by your instructor).

Answer:

Algorithm:

 Start
 Define variable eng, phy, chem, maths, comp, sum, average
 Input marks of five subjects. Store it in some variables say eng, phy, chem, math and comp
 Calculate sum of all subjects and store in total = eng + phy + chem + math + comp and store in
variable sum
 Divide sum of all subjects by total number of subject to find average i.e. average = sum / 5.
 Calculate percentage using percentage = (total / 500) * 100.
 Finally, print resultant values total, average and percentage.
 End

Program:

Program to display the grade of student


1. import java.util.Scanner;
2. public class JavaExample
3. {
4. public static void main(String args[])
5. {
6. /* This program assumes that the student has 6 subjects,
7. * thats why I have created the array of size 6. You can
8. * change this as per the requirement.
9. */
10. int marks[] = new int[6];
11. int i;
12. float total=0, avg;
13. Scanner scanner = new Scanner(System.in);
14.
15.
16. for(i=0; i<6; i++) {
17.
18. System.out.print("Enter Marks of Subject"+(i+1)+":");
19. marks[i] = scanner.nextInt();
20. total = total + marks[i];
21. }
22. scanner.close();
23. //Calculating average here
24. avg = total/6;
25. System.out.print("The student Grade is: ");
26. if(avg>=80)
27. {
28. System.out.print("A");
29. }
30. else if(avg>=60 && avg<80)
31. {
32. System.out.print("B");
33. }
34. else if(avg>=40 && avg<60)
35. {
36. System.out.print("C");
37. }
38. Else
39. {
40. System.out.print("D");
41. }
42. }
43. }
Output:
Enter Marks of Subject1:40
Enter Marks of Subject2:80
Enter Marks of Subject3:80
Enter Marks of Subject4:40
Enter Marks of Subject5:60
Enter Marks of Subject6:60
The student Grade is: B
Question 4 Part (A)

What do you understand by a multiple stack? How is it useful? Also explain the concept of stack
overflow and underflow.

Answer:

What is Stack:
In computer science, a stack is an abstract data type that serves as a collection of elements, with two
principal operations:

 Push, which adds an element to the collection


 Pop, which removes the most recently added element that was not yet removed.

The order in which elements come off a stack gives rise to its alternative name, LIFO (last in, first out).
Additionally, a peek operation may give access to the top without modifying the stack.[1] The name "stack"
for this type of structure comes from the analogy to a set of physical items stacked on top of each other,
which makes it easy to take an item off the top of the stack, while getting to an item deeper in the stack may
require taking off multiple other items first

Considered as a linear data structure, or more abstractly a sequential collection, the push and pop operations
occur only at one end of the structure, referred to as the top of the stack. This makes it possible to implement
a stack as a singly linked list and a pointer to the top element. A stack may be implemented to have a
bounded capacity. If the stack is full and does not contain enough space to accept an entity to be pushed,
the stack is then considered to be in an overflow state. The pop operation removes an item from the top of
the stack.

Basic Architecture of Stack:

A typical stack, storing local data and call information for nested procedure calls (not necessarily nested
procedures). This stack grows downward from its origin. The stack pointer points to the current topmost
datum on the stack. A push operation decrements the pointer and copies the data to the stack; a pop operation
copies data from the stack and then increments the pointer. Each procedure called in the program stores
procedure return information (in yellow) and local data (in other colors) by pushing them onto the stack.
This type of stack implementation is extremely common, but it is vulnerable to buffer overflow attacks.
A typical stack is an area of computer memory with a fixed origin and a variable size. Initially the size of
the stack is zero. A stack pointer, usually in the form of a hardware register, points to the most recently
referenced location on the stack; when the stack has a size of zero, the stack pointer points to the origin of
the stack.
There are many variations on the basic principle of stack operations. Every stack has a fixed location in
memory at which it begins. As data items are added to the stack, the stack pointer is displaced to indicate
the current extent of the stack, which expands away from the origin.
Stack pointers may point to the origin of a stack or to a limited range of addresses either above or below
the origin (depending on the direction in which the stack grows); however, the stack pointer cannot cross
the origin of the stack. In other words, if the origin of the stack is at address 1000 and the stack grows
downwards (towards addresses 999, 998, and so on), the stack pointer must never be incremented beyond
1000 (to 1001, 1002, etc.). If a pop operation on the stack causes the stack pointer to move past the origin
of the stack, a stack underflow occurs. If a push operation causes the stack pointer to increment or decrement
beyond the maximum extent of the stack, a stack overflow occurs.
Applications of Stack:

 Expression evolution and syntax parsing:


Calculators employing reverse Polish notation use a stack structure to hold values. Expressions can
be represented in prefix, postfix or infix notations and conversion from one form to another may
be accomplished using a stack. Many compilers use a stack for parsing the syntax of expressions,
program blocks etc. before translating into low level code. Most programming languages are
context-free languages, allowing them to be parsed with stack based machines.
 Backtracking:
Another important application of stacks is backtracking. Consider a simple example of finding the
correct path in a maze. There are a series of points, from the starting point to the destination. We
start from one point. To reach the final destination, there are several paths. Suppose we choose a
random path. After following a certain path, we realize that the path we have chosen is wrong. So
we need to find a way by which we can return to the beginning of that path. This can be done with
the use of stacks. With the help of stacks, we remember the point where we have reached. This is
done by pushing that point into the stack. In case we end up on the wrong path, we can pop the last
point from the stack and thus return to the last point and continue our quest to find the right path.
This is called backtracking.
The prototypical example of a backtracking algorithm is depth-first search, which finds all vertices
of a graph that can be reached from a specified starting vertex. Other applications of backtracking
involve searching through spaces that represent potential solutions to an optimization problem.
Branch and bound is a technique for performing such backtracking searches without exhaustively
searching all of the potential solutions in such a space.
 Compile Time memory management:
A number of programming languages are stack-oriented, meaning they define most basic operations
(adding two numbers, printing a character) as taking their arguments from the stack, and placing
any return values back on the stack. For example, PostScript has a return stack and an operand
stack, and also has a graphics state stack and a dictionary stack. Many virtual machines are also
stack-oriented, including the p-code machine and the Java Virtual Machine.
Almost all calling conventions—the ways in which subroutines receive their parameters and return
results—use a special stack (the "call stack") to hold information about procedure/function calling
and nesting in order to switch to the context of the called function and restore to the caller function
when the calling finishes. The functions follow a runtime protocol between caller and called to save
arguments and return value on the stack. Stacks are an important way of supporting nested or
recursive function calls. This type of stack is used implicitly by the compiler to support CALL and
RETURN statements (or their equivalents) and is not manipulated directly by the programmer.
Some programming languages use the stack to store data that is local to a procedure.
Space for local data items is allocated from the stack when the procedure is entered, and is
reallocated when the procedure exits. The C programming language is typically implemented in
this way. Using the same stack for both data and procedure calls has important security implications
(see below) of which a programmer must be aware in order to avoid introducing serious security
bugs into a program.

Security:

Some computing environments use stacks in ways that may make them vulnerable to security breaches and
attacks. Programmers working in such environments must take special care to avoid the pitfalls of these
implementations.
For example, some programming languages use a common stack to store both data local to a called
procedure and the linking information that allows the procedure to return to its caller. This means that the
program moves data into and out of the same stack that contains critical return addresses for the procedure
calls. If data is moved to the wrong location on the stack, or an oversized data item is moved to a stack
location that is not large enough to contain it, return information for procedure calls may be corrupted,
causing the program to fail.
Malicious parties may attempt a stack smashing attack that takes advantage of this type of implementation
by providing oversized data input to a program that does not check the length of input. Such a program may
copy the data in its entirety to a location on the stack, and in so doing it may change the return addresses
for procedures that have called it. An attacker can experiment to find a specific type of data that can be
provided to such a program such that the return address of the current procedure is reset to point to an area
within the stack itself (and within the data provided by the attacker), which in turn contains instructions
that carry out unauthorized operations.
This type of attack is a variation on the buffer overflow attack and is an extremely frequent source of
security breaches in software, mainly because some of the most popular compilers use a shared stack for
both data and procedure calls, and do not verify the length of data items. Frequently programmers do not
write code to verify the size of data items, either, and when an oversized or undersized data item is copied
to the stack, a security breach may occur.

Question 4 Part (B)

How a stack implemented using a linked list differ from a stack does implemented using an array?
Explain with the help of pseudo-code.

Answer:

Implement a stack using singly linked list:

Implement a stack using single linked list concept. All the single linked list operations perform based on
Stack operations LIFO(last in first out) and with the help of that knowledge we are going to implement a
stack using single linked list. using single linked lists so how to implement here it is linked list means what
we are storing the information in the form of nodes and we need to follow the stack rules and we need to
implement using single linked list nodes so what are the rules we need to follow in the implementation of
a stack a simple rule that is last in first out and all the operations we should perform so with the help of a
top variable only with the help of top variables are how to insert the elements let’s see

Implement a stack using singly linked list:


Implement a stack using single linked list concept. all the single linked list operations perform based on
Stack operations LIFO(last in first out) and with the help of that knowledge we are going to implement a
stack using single linked list. using single linked lists so how to implement here it is linked list means
what we are storing the information in the form of nodes and we need to follow the stack rules and we
need to implement using single linked list nodes so what are the rules we need to follow in the
implementation of a stack a simple rule that is last in first out and all the operations we should perform so
with the help of a top variable only with the help of top variables are how to insert the elements let’s see.
A stack can be easily implemented through the linked list. In stack Implementation, a stack contains a top
pointer. which is “head” of the stack where pushing and popping items happens at the head of the list.
first node have null in link field and second node link have first node address in link field and so on and
last node address in “top” pointer.
The main advantage of using linked list over an arrays is that it is possible to implements a stack that can
shrink or grow as much as needed. In using array will put a restriction to the maximum capacity of the
array which can lead to stack overflow. Here each new node will be dynamically allocate. so overflow is
not possible.
Stack Operation:
push() : Insert the element into linked list nothing but which is the top node of Stack.
pop() : Return top element from the Stack and move the top pointer to the second node of linked list or
Stack.
peek(): Return the top element.
display(): Print all element of Stack.

Question 5 Part (A)

Differentiate between an interactive function and a recursive function. Which one will you prefer to
use and in what circumstances?

Answer:

Definition:
A program is called recursive when an entity calls itself. A program is call iterative when there is a loop
(or repetition).
Example: Program to find the factorial of a number

// C++ program to find factorial of given number

1. #include<bits/stdc++.h>
2. using namespace std;
3.
4. // ----- Recursion -----
5. // method to find factorial of given number
6. int factorialUsingRecursion(int n)
7. {
8. if (n == 0)
9. return 1;
10.
11. // recursion call
12. return n * factorialUsingRecursion(n - 1);
13. }
14.
15. // ----- Iteration -----
16. // Method to find the factorial of a given number
17. int factorialUsingIteration(int n)
18. {
19. int res = 1, i;
20.
21. // using iteration
22. for (i = 2; i <= n; i++)
23. res *= i;
24.
25. return res;
26. }
27.
28. // Driver method
29. int main()
30. {
31. int num = 5;
32. cout << "Factorial of " << num <<
33. " using Recursion is: " <<
34. factorialUsingRecursion(5) << endl;
35.
36. cout << "Factorial of " << num <<
37. " using Iteration is: " <<
38. factorialUsingIteration(5);
39.
40. return 0;
41. }

Output:
Factorial of 5 using Recursion is: 120
Factorial of 5 using Iteration is: 120
Below are the detailed example to illustrate the difference between the two:

 Time Complexity:
Finding the Time complexity of Recursion is more difficult than that of Iteration.
 Recursion: Time complexity of recursion can be found by finding the value of the nth recursive
call in terms of the previous calls. Thus, finding the destination case in terms of the base case, and
solving in terms of the base case gives us an idea of the time complexity of recursive equations.
 Iteration: Time complexity of iteration can be found by finding the number of cycles being
repeated inside the loop.
 Usage: Usage of either of these techniques is a trade-off between time complexity and size of
code. If time complexity is the point of focus, and number of recursive calls would be large, it is
better to use iteration. However, if time complexity is not an issue and shortness of code is,
recursion would be the way to go.
 Recursion: Recursion involves calling the same function again, and hence, has a very small
length of code. However, as we saw in the analysis, the time complexity of recursion can get to
be exponential when there are a considerable number of recursive calls. Hence, usage of recursion
is advantageous in shorter code, but higher time complexity.
 Iteration: Iteration is repetition of a block of code. This involves a larger size of code, but the
time complexity is generally lesser than it is for recursion.
 Overhead: Recursion has a large amount of Overhead as compared to Iteration.
 Recursion: Recursion has the overhead of repeated function calls that is due to repetitive calling
of the same function, the time complexity of the code increases manifold.
 Iteration: Iteration does not involve any such overhead.
 Infinite Repetition: Infinite Repetition in recursion can lead to CPU crash but in iteration, it will
stop when memory is exhausted.
 Recursion: In Recursion, Infinite recursive calls may occur due to some mistake in specifying
the base condition, which on never becoming false, keeps calling the function, which may lead to
system CPU crash.
 Iteration: Infinite iteration due to mistake in iterator assignment or increment, or in the
terminating condition, will lead to infinite loops, which may or may not lead to system errors, but
will surely stop program execution any further.

PROPERTY RECURSION ITERATION

Definition Function calls itself. A set of instructions repeatedly

executed.

Application For functions. For loops.

Termination Through base case, where there When the termination condition for the

will be no function call. iterator ceases to be satisfied.

Usage Used when code size needs to be Used when time complexity needs to be

small, and time complexity is not balanced against an expanded code size.

an issue.

Code Size Smaller code size Larger Code Size.

Time Very high(generally exponential) Relatively lower time

Complexity time complexity. complexity(generally polynomial-

logarithmic).

Question 5 Part (B)


Write a program to input two stacks and compare their contents.

Answer:

Approach:
Take a flag variable and set it to true initially, flag = true. This variable will indicate whether the stacks
are same or not.
• First check if the size of given stack1 and stack2 are equal. If the size is not equal, set flag to false
and return it.
• If the size is same, then compare the top elements of both of the given stacks.
• If the top of both stacks is NOT same, set flag to false and return it otherwise pop top elements of
both stacks.
• Repeat step 3 and 4 until all elements are popped out from both of the stacks.
• If both stacks gets empty and the flag variable is still true, it means that the stacks are same.

// C++ program to check if the given


// stacks are equal or not
1. #include <bits/stdc++.h>
2. using namespace std;
3.
4. // Function to check if the two given
5. // stacks are same
6. bool isSameStack(stack<string> stack1, stack<string> stack2)
7. {
8. // Create a flag variable
9. bool flag = true;
10.
11. // Check if size of both stacks are same
12. if (stack1.size() != stack2.size()) {
13. flag = false;
14. return flag;
15. }
16.
17. // Until the stacks are not empty
18. // compare top of both stacks
19. while (stack1.empty() == false) {
20. // If the top elements of both stacks
21. // are same
22. if (stack1.top() == stack2.top()) {
23. // Pop top of both stacks
24. stack1.pop();
25. stack2.pop();
26. }
27. else {
28. // Otherwise, set flag to false
29. flag = false;
30. break;
31. }
32. }
33.
34. // Return flag
35. return flag;
36. }
37.
38. // Driver Code
39. int main()
40. {
41. // Creating stacks
42. stack<string> stack1;
43. stack<string> stack2;
44.
45. // Inserting elements to stack1
46. stack1.push("Geeks");
47. stack1.push("4");
48. stack1.push("Geeks");
49. stack1.push("Welcomes");
50. stack1.push("You");
51.
52. // Inserting elements to stack2
53. stack2.push("Geeks");
54. stack2.push("4");
55. stack2.push("Geeks");
56. stack2.push("Welcomes");
57. stack2.push("You");
58.
59. if (isSameStack(stack1, stack2))
60. cout << "Stacks are Same";
61. else
62. cout << "Stacks are not Same";
63.
64. return 0;
65. }

Output:
Stacks are Same

Das könnte Ihnen auch gefallen