You are on page 1of 22

Assignment # 01

Department of Electrical Engineering


HITEC University, Taxila

BS Electrical Engineering Program


(Session 2018)

EC-222 Data Structures and Algorithms

Submitted by:
Muhammad Humaish
Reg# 18-BSEE-029

Instructor: Sir, WAQAR ISMAIL


Question No 1:
A. Explain the basic concept of stack data structure.
B. Describe the types, and operations performed on data structures.
C. Write C++ program to perform following implementation of Stack with all
essential
operations,
1. Array based implementation
2. Linked List based implementation
D. What are the principle differences between arrays and structures? How
address
calculations are performed for the access of an item for each.
E. Implement a program that pops alternate elements from a STACK and
builds a new
Stack from it. Finally, you will have two STACKS: one the original with
alternate
elements deleted and the other the new stack

Answer A:
A collection of items in which only the most recently item may be removed. The
latest added item is at the top. Basic operation is push and pop. Mostly Top and is
empty are available too. Also known as "last in, first out" or LIFO

Answer B:
Data structure are used to store data in the computer in an organized manner. The
scheme of organization of related information is also known as "data structure".
Different types of data structure are as follow.
Stacks:
Works in first in last out order. The element inserted first is removed last.
Queue:
First in first out order. The element inserted first is removed first.
Linked list:
Sorted data in a linear fashion.
Trees:
Sorted data in a nonlinear fashion with one root node and sub nodes.
Lists:
a group of similar elements with connectivity to the previous or next data
elements.
Arrays:
A set of homogenous values.
Records:
A set if field, where each field consist of data belong to a type of data.
Tables:
the data is preserved in the form of rows and columns. These are like the records,
where the result or data manipulation is reflected for the entire table.

Operations:
The operations most used in the data structure are broadly classified into the
following type
Create:
The creation operation results in the memory reserve for program elements. This
can be done by declaration statement. The creation of the data structure can take
place during compilation time or execution time. The malloc () function of the C
language is used for creation.
Destroy:
The destruction operation destroys the allocated memory space for the specified
data structure. The free () function of the C language is used to destroy the data
structure.
Selection:
The selection operation tries to access data within a data structure.
Update:
Update or modify the data in data structure
Search:
Find the presence of the desired data item in the list of data items, you can also
find the locations of all items that satisfy certain conditions.
Classification:
Classification is a process of organizing all data elements in a data structure in an
order, for example, in ascending or descending order.
Merge:
Merging is a process of combining the data elements of two different ordered lists
into a single ordered list.
Division:
Division is a process of splitting a single list to a multiple list.
Tour: - Tour is a process of visiting each node in a list systematically.

Answer C:
Array Based Implementation.
Program:
#include<iostream>
using namespace std;

int Stack[10], Top;

void IntiStack()
{
Top = -1;
}

int IsEmpty()
{
if (Top == -1)
return 1;
else
return 0;
}

int IsFull()
{
if (Top == 5 - 1)
return 1;
else
return 0;
}

void Push(int X)
{
if (IsFull()) {
cout << "Stack Is Full:" << endl;
return;
}
++Top;
Stack[Top] = X;
cout << X << " Has Been Inserted:" << endl;
}

void Display() {
int i;
if (IsEmpty()) {
cout << "STACK is EMPTY." << endl;
return;
}
for (i = Top; i >= 0; i--)
{
cout << Stack[i] << endl;
}
cout << endl;
}

void Pop() {
int temp;
if (IsEmpty()) {
cout << "STACK Is Empty:" << endl;
return;
}

temp = Stack[Top];
Top--;
cout << temp << " Has Been Deleted:" << endl;
}
int main() {
int X;
IntiStack();
char Z;
do {
int Y;
cout << "Chosse \n1.Push Number\n" << "2.Pop Number\n" << "3.Display
Stack\n";
cout << "Please Select An Option : ";
cin >> Y;
switch (Y)
{
case 1:
cout << "Enter An Integer Number: ";
cin >> X;
Push(X);
break;

case 2:
Pop();
break;

case 3:
Display();
break;

default:
cout << "Choose A Valid Optoion:\n";

}
cout << "Do You Want To Continue? ";
cin >> Z;
} while (Z == 'Y' || Z == 'y');
return 0;
}
Link List Based implementation.

Program:
#include<iostream>
using namespace std;

struct Node
{
int Data;
Node* next;
}*Top = NULL, * X;

Node* Newnode(int Z)
{
X = new Node;
X->Data = Z;
X->next = NULL;
return(X);
}

void Push(Node* Y)
{
if (Top == NULL)
Top = Y;
else
{
Y->next = Top;
Top = Y;
}
}
void Pop() {
if (Top == NULL)
{
cout << "Stack Is Empty :"<<endl;
}
else
{
cout << "Deleted Number Is :" << Top->Data;
X = Top;
Top = Top->next;
delete(X);
}
}

void Display()
{
Node* Y;
Y = Top;

if (Top == NULL)
{
cout << "Stack Is Empty"<<endl;
}
else {
while (Y != NULL)
{
cout << Y->Data << " ";
Y = Y->next;
}
}
}

int main()
{
int num, Z;
Node* Temp;

while (1)
{
cout << "\n\n1.PUSH The Number: \n2.POP The Number: \n3.Display The
Stack: \n4.Exit :";
cout << "\n Select An Option :";
cin >> num;

switch (num)
{
case 1: cout << "\n Enter The Number";
cin >> Z;
Temp = Newnode(Z);
Push(Temp);
break;

case 2: Pop();
break;

case 3: Display();
break;

case 4: exit(0);

default: cout << "\n Choose A Valid Option";


}
}

return 0;
}
Answer D:
Arrays:
1. An array is a collection of variables that have the same data type.
2. Syntax of array is type_array name [size].
3. You can access an array element by their index number.
4. Element that are stored in array are of same size.
5. You can Not Define Bit Filed in array.
6. You don not required a keyword for array deceleration.

Structures:
1. Structure contain variables of different data type.
2. Syntax of structure is struct_strct name
{type element 1; type element 2;} variable 1, variable2;
3. You can access a structure element by their name.
4. Element that are stored in structure are of different Size.
5. You can define bit filed in structure.
6. You required a key word for structure deceleration that is struct.

Address Calculation:

Let’s create an array and calculate it’s address by using following formula.
Address of Array [ J] = A + B * (X– YA)
In this equation,
A = This is the Base address of the array.
B = Indicate the Size of an element that is stored in an array.
X = This is the Subscript of an element whose address you want to find.
YA = This is lower limit / lower bound of subscript, if not specified assume 0
(zero)

Colum-X-Colum:
Loc (B[J][K]) = Base (B) + A [Z x K + J]

Row-X-Row:
Location (B [J][K]) = Base (B) + A [Y x J + K]

A denotes the size, that is, ‫ ؛‬number of bytes per data element of the matrix B ،
Z is the total number of rows and Y is the total number of columns in the
matrix.

Answer E:

Program:
#include<iostream>
using namespace std;

int Stack[5], Top, Stack2[5], Top2;

void IntiStack()
{
Top = -1;
}

void IntiStack2()
{
Top2 = -1;
}

int IsEmpty()
{
if (Top == -1)
return 1;
else
return 0;
}
int isempty2()
{
if (Top2 == -1)
return 1;
else
return 0;
}
int isfull2()
{
if (Top2 == 5 - 1)
return 1;
else
return 0;
}
int IsFull()
{
if (Top == 5 - 1)
return 1;
else
return 0;
}

void Push(int X)
{
if (IsFull()) {
cout << "Stack 1 Is Full:" << endl;
return;
}
++Top;
Stack[Top] = X;
cout << X << " Has Been Inserted in Stack 1:" << endl;
}

void Push2(int Z)
{
if (isfull2())
{
cout << "Stack 2 Is Full:" << endl;
return;
}
++Top2;
Stack2[Top2] = Z;
cout << Z << " Has Been Inserted In Stack 2:" << endl;
}

void Display() {
int i, j;
if (IsEmpty()) {
cout << "STACK 1 is EMPTY." << endl;
return;
}
cout << "Stack 1 Elements are : " << endl;
for (i = Top; i >= 0; i--)
{
cout << Stack[i] << endl;
}

if (isempty2())
{
cout << "STACK 2 is EMPTY." << endl;
return;
}

cout << "Stack 2 Elements are : " << endl;


for (j = Top2; j >= 0; j--)
{
cout << Stack2[j] << endl;
}
cout << endl;
}
void Pop()
{
int temp, Z;
if (IsEmpty()) {
cout << "STACK Is Empty:" << endl;
return;
}
Z = Stack[Top];
Push2(Z);
temp = Stack[Top];
Top--;
cout << temp << " Has Been Deleted:" << endl;
}

int main()
{
int X;
IntiStack();
IntiStack2();
char Z;
do {
int Y;
cout << "Chosse \n1.Push Number\n" << "2.Pop Number\n" << "3.Display
Stack\n";
cout << "Please Select An Option : ";
cin >> Y;
switch (Y)
{
case 1:
cout << "Enter An Integer Number: ";
cin >> X;
Push(X);
break;

case 2:
Pop();
break;

case 3:
Display();
break;

default:
cout << "Choose A Valid Optoion:\n";

}
cout << "Do You Want To Continue? ";
cin >> Z;
} while (Z == 'Y' || Z == 'y');
return 0;
}
Question 2:

A. Explain the analysis of algorithms in context of time and space complexity.


B. Discuss the different notations used for algorithms.
C. Give time complexities of arrays, link list (single, double and circular),
stakes and queues in tabular form.
Answer A:
Time Complexity of Algorithm:
The complexity of the algorithm means the total time required for the program to
run until it is completed.

The temporal complexity of algorithms is commonly expressed using large O


notation. It is an approach to represent the complexity of time. We will study it
in detail in the following tutorial.

The complexity of time is commonly estimated by calculating the number of


initial steps any algorithm performs to complete execution. As in the previous
example, for the first code, the n-loop will execute the number of times, so the
complexity of time 'while for the second code, the complexity of time is constant,
because it will never depend on the value of n, but it will be null

Because the performance of the algorithm can vary depending on the types of
input data, therefore, for the algorithm, we usually use the complexity of the
algorithm time in the worst case because this is the maximum time required for
any size. Input.

Now let's look at the next big issue of time complexity, which is how to calculate
the complexity of time. Sometimes it becomes very confusing, but we will try to
explain it in the simplest way.

Now, the most common measure for calculating the complexity of time is the
notation of Big O, eliminating all constant factors so that the execution time can
be estimated relative to N, where N approaches infinity. In general, you can think
of it like this:

Above we have only one statement. Temporal complexity will be constant. The
ad execution time will not change for N.
The time complexity of the above program will be linear. Running of the loop is
proportional to Running time becomes double when N become double.

the time complexity of the above code will be quadratic. The execution time of
the two rings is proportional to the N box. When N is doubled, the execution time
increases by N * N

Space Complexity of Algorithm:


The spatial complexity of an algorithm determines how much space or memory
the algorithm needs to perform based on input length.

When calculating the spatial complexity of any algorithm, we consider only the
data space and neglect the educational space and the environmental stack.

Data Space:
The amount of space used by constant and Variabels.

Calculating the Space Complexity:


To calculate the complexity of space, we need to know the value of memory used
by different types of data type variables, the method of calculating the space
complexity of two variables from different operating system is same.
Now Let’s Calculate the Space Complexity of the following example

In the Above expression, the variables a, b and c, z are all sorts of integers,
therefore, they occupy 4 bytes each, so the total memory requirements will be (4
(4) + 4) = 20 bytes, these 4 additional bytes are for the return value. Because this
space condition is set in the previous example, it is called "Constant Space
Complexity."

Answer B:
Notations Used for Algorithm:
The Theta Notation:
Theta notation limits the functions of the top and bottom, so you know the exact
approximate behavior.
A simple way to get this type of notation is by ignoring Leading constant and
drop low order terms. Let’s consider the following expression,
3n^3 + 6n^2+ 6000 = Θ (n3)
The dropping of lower order terms is a good method because there will always
be a n0 after which (n3) has values greater than 2n2) regardless of the constants
involved.
For a given function g (n), we indicate that Θ (g (n)) follows a set of functions
The above Expression means that if f (n) is a theta of g(f), the value f (n) is always
between c1 * g (n) and c2 * g (n) for the large values of n (n> = N0). The
definition of theta also requires that f (n) is not negative for n values greater than
n0

The Big O Notation:


This notation tells us about the upper bound of algorithm, it limit only one
function from the top. For example, consider the insertion sort case. It takes linear
time in the best case and square time in the worst case. We can safely say that the
time complexity of the insertion regularization is O (n ^ 2). Note that O (n ^ 2)
also covers linear time.
The Big O notation is useful only when we have the upper bound for the time
complexity of the algorithm. Many times, we can easily find the upper bound by
looking at the algorithm.

The Omega Notation:


This notation expresses the minimum time of implementation of the algorithm. It
measures the time complexity of the best case or the best amount of time the
algorithm can take to complete.
Answer C:

Arrays Stacks Queues Single Double Circular


Link Link Link
List List List
Array access is Stack access is Queue access is access is access is access is O
O (1) O (n) O (n) O (n) O (n) (n)

Array Search is Stack Search is Queue Search is Search is Search is Search is O


O (n) O (n) O (n) O (n) O (n) (n)

If the array is
sorted.
Array access is
O (log n)
Array insert is Stack insert is Queue insert is insert is insert is insert is
O (n) O (1) O (1) (Start or (Start or (Start or
end) end) end)
O (1) O (1) O (1)
Array Deletion Stack Deletion Queue Deletion Deletion Deletion Deletion is
is O (n) is O (1) is O (1) is (Start is (Start (Start or
or end) or end) end)
O (1) O (1) O (1)

Question No 3:
A. Define linked list. How linked lists are represented in memory.
B. Write a program to check if the linked list is a palindrome.

Answer A:
A linked list is a data structure that can store an indefinite number of items. These
items are connected using pointers in a sequential manner.
To Represent a link in a memory you only need two arrays only know as LINK
and INFO, such that INFO[k] contain the information of the element and LINK[k]
contain the address to the next node.
Start Variable is used to indicate the beginning location of the list and NULL
indicated the end of the list.
Answer B:

Program:
#include<iostream>
#include <stdlib.h> //General Pupose Standard Library Of C++
//Ued For The Malloc To create New Node
using namespace std;

struct Node
{
int data;
struct Node* next;
};

void Push(struct Node** head, int Value)


{
struct Node* Temp = (struct Node*)malloc(sizeof(struct Node));

Temp->data = Value;
Temp->next = *head;
*head = Temp;
}

int CheckPal(struct Node** X, struct Node* Y)


{
if (Y == NULL)
return 1;

int Num = CheckPal(X, Y->next) && ((*X)->data == Y->data);


(*X) = (*X)->next;

return Num;
}

int Check(struct Node* head)


{
return CheckPal(&head, head);
}

int main(void)
{
int Array[] = { 1, 3, 5, 6, 7 };
int N = sizeof(Array) / sizeof(Array[0]);

struct Node* head = NULL;


for (int j = N - 1; j >= 0; j--)
Push(&head, Array[j]);

if (Check(head))

cout << "The Linked List Is Palindrome ";


else
cout << "the Linked List Is Not Palindrome";

return 0;
}

Question no 4:
A. What is infix, postfix and prefix notations?
B. Give a graphical trace for the translation of given infix string to polish and
reverse
polish string. A * B + C / D – E
Answer A:
Infix notations:
Operators are usually Written In-Between Their Operands Such as (G+H)
Or (A*B)/C etc.

Postfix notations:
In this notation we write the operators after the operands for example GH+ or
ABC*D/ etc.
prefix notations:
In this notation we write the operands after the operators for example +GH or
/*A+BCD etc.

Answer B:

Infix string
A*B+C/D–E

Infix to Postfix string:

AB*CD–E/+

Infix to Prefix String:


+*AB/CD-E

You might also like