0% found this document useful (0 votes)
16 views

Assignment 1

The document discusses abstract data types, binary search, and algorithms. It provides examples of abstract data types like stacks. It also describes inserting and deleting from an unsorted array and searching in it. Time complexities of different algorithms are analyzed.

Uploaded by

Gillani Aleem
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
16 views

Assignment 1

The document discusses abstract data types, binary search, and algorithms. It provides examples of abstract data types like stacks. It also describes inserting and deleting from an unsorted array and searching in it. Time complexities of different algorithms are analyzed.

Uploaded by

Gillani Aleem
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 6

BINARY SEARCH, UNSORTED ARRAY, ABSTRACT

DATA TYPE, TIME COMPLEXITIES

ASSIGNMENT #01
COMP-201 DATA STRUCTURE & ALGORITHM

SUBMITTED BY
MUHAMMAD ALI

Reg No. B22F0859SE044


Software Engineering 22 (Green)

SUBMITTED TO
SIR RIZWAN ALI

DEPARTMENT OF IT & COMPUTER SCIENCE

PAK-AUSTRIA FACHHOCHSCHULE INSTITUTE OF APPLIED


SCIENCES AND TECHNOLOGY
QUESTION 1
What is an "Abstract Data Type" (ADT) in the context of data structures? Provide an example of
an ADT and explain why it is useful.

ANSWER
Definition:
In the context of data structures, a "Abstract Data Type" (ADT) is a high-level specification of a
data structure that describes its behavior and the operations that may be carried out on it, without
defining the underlying implementation details.

Example:
A classic example of an ADT is a "Stack." The stack ADT specifies two primary operations:
1. Push: Adds an element to the top of the stack.
2. Pop: Removes and returns the top element of the stack.

Importance:
When you can concentrate on how data is utilized and handled instead of its internal
representation, ADTs are helpful because they offer an abstraction. It is easier to reason about and
maintain complicated systems when concerns are separated, which is why this abstraction is useful
for software design and development. Furthermore, as long as the interface stays consistent, ADTs
allow you to modify the underlying implementation without impacting the code that uses them.
--------------------------------------------------------------------------------------------------------------------
Question 2
Imagine you are searching for a number in a list using Binary Search, and you've already made
two comparisons (i.e., you've reduced your search space twice). If the list originally had 64
elements:
a. How many elements are you considering after these two reductions?
b. Explain why Binary Search would not work efficiently if the list were not sorted.
ANSWER:
a. You are taking into consideration one-fourth of the initial list size in each of the two reductions
you made in a binary search on a list with 64 elements. After the first comparison, you have 32
elements to take into consideration, and after the second comparison, you have 16 elements
remaining to search through. This is how binary search works: it repeatedly divides the search
space in half.
b. Binary search operates under the presumption that the list is ordered either ascending or
descending. For the algorithm to function well, this supposition is essential. Binary search won't
function effectively if the list isn't sorted because it might miss the target element or need a lot
more comparisons.

Explanation
The midpoint of the list during each comparison may not precisely split the data into two
equal parts if the list is not sorted. The target element might not be in the half of the list you are
looking at as a result of this. In this case, you would need to investigate both halves of the list
linearly, thereby converting the binary search into a linear search. With a time complexity of O(n),
where 'n' is the number of elements in the list, binary search on an unsorted list may, in the worst
case, end up being just as slow as a straightforward linear search.
---------------------------------------------------------------------------------------------------------------------
Question 3
Consider an unsorted array of integers. Write a program that.
a. Inserts a new number at the third position.
b. Deletes the number at the fifth position.
c. Searches for a number and returns its index (or a message if not found).
ANSWER:
a) Insertion at the Third Position:
int newNumber = 11;
int positionToInsert = 2; // 0-based index
for (int i = 9; i > positionToInsert; i--) {
arr[i] = arr[i - 1];
}
arr[positionToInsert] = newNumber;
b) Deletion of the Fifth Position:
int positionToDelete = 4; // 0-based index
for (int i = positionToDelete; i < 9; i++) {
arr[i] = arr[i + 1];
}
c) Searching for a Number:
int targetNumber = 7;
int index = -1;
for (int i = 0; i < 10; i++) {
if (arr[i] == targetNumber) {
index = i;
break;
}
}
if (index != -1) {
cout << "Number found at index " << index << endl;
} else {
cout << "Number not found in the array." << endl;
}

Complete Program:
#include <iostream>
#include <vector>
int main() {
std::vector<int> arr = {10, 20, 30, 40, 50, 60, 70}; // Example unsorted array
// a. Insert a new number at the third position
int newNumber = 25;
arr.insert(arr.begin() + 2, newNumber); // Third position is index 2
// Display the updated array after insertion
std::cout << "Array after insertion: ";
for (int num : arr)
OUTPUT
{
std::cout << num << " ";
}
std::cout << std::endl;
// b. Delete the number at the fifth position
int deletePosition = 4; // Fifth position is index 4
if (deletePosition >= 0 && deletePosition < arr.size()) {
arr.erase(arr.begin() + deletePosition);
}
// Display the updated array after deletion
std::cout << "Array after deletion: ";
for (int num : arr) {
std::cout << num << " ";
}
std::cout << std::endl;
// c. Search for a number and return its index (or a message if not found)
int searchNumber = 30; // Number to search for
int index = -1; // Initialize index to -1 as a "not found" flag
for (int i = 0; i < arr.size(); i++) {
if (arr[i] == searchNumber) {
index = i;
break; // Number found, exit the loop
}
}
if (index != -1) {
std::cout << "Number " << searchNumber << " found at index " << index << std::endl;
} else {
std::cout << "Number " << searchNumber << " not found in the array." << std::endl;
}
return 0;
}
---------------------------------------------------------------------------------------------------------------------
Question 4
Given two algorithms A and B with time complexities O(n2) and Ω (log n) respectively.
a. Which algorithm would likely be faster for sufficiently large input sizes? Justify your answer.
b. Is it always guaranteed that algorithm B will be faster than algorithm A for all input sizes?
Explain your answer considering the asymptotic notations provided.

Answer:
a). If the input sizes are large enough, Algorithm B, which has a time complexity of Ω(log n), is
probably going to be faster. This is the explanation:
➢ Comprehending Complexities of Time:
Algorithm A:
With an O(n^2) time complexity, Algorithm A's execution time increases quadratically as
the size of the input. This suggests that the running time of A will expand noticeably faster as the
input size increases.
Algorithm B
Algorithm B has a lower bound on its running time because of its Ω(log n) time complexity.
Stated otherwise, the growth rate decreases and the running time grows logarithmically with the
input size. Compared to quadratic growth, logarithmic growth is far slower.

➢ Comparing Rates of Growth:


When n is big enough, quadratic growth (O(n^2)) grows substantially faster than logarithmic
growth (Ω(log n)). The performance difference between the two methods grows in favor of
Algorithm B as the input size increases.

➢ Empirical Findings:
Because of the disparity in their growth rates, Algorithm B is anticipated to perform better than
Algorithm A in real-world situations when input sizes are large enough. As the input size grows,
Algorithm B's performance advantage becomes more apparent.

b). No, not all input sizes will result in Algorithm B being faster than Algorithm A in every
case. This is because temporal complexities like O(n^2) and Ω(log n) only indicate upper and
lower constraints on the running time; they don't provide details about hidden constants, constant
factors, or the point at which one approach outperforms the other.
In real-world situations, Algorithm A (O(n2)) may be faster for modestly sized inputs or
Algorithm B ((log n)) may be impracticable because of undetected overhead. Asymptotic
analysis ignores constant factors and other real-world issues, providing only a broad
understanding of the algorithms' behavior as input sizes go to infinity.
---------------------------------------------------------------------------------------------------------------------

You might also like