Aamir - DSA Assignment
Aamir - DSA Assignment
Q-1) What is Data Structure? Write Definitions, Operations, and Applications of data structures.
ANS.
1. A data structure is a specialized format for organizing, processing, and storing
data in a computer’s memory. It enables efficient access and manipulation of data,
allowing programmers to perform specific tasks more effectively. In simpler terms,
data structures provide a way to arrange and manage data so that it can be accessed
and updated efficiently.
➢ Traversing:
• Traversing a data structure means visiting each element stored
within it.
• It can be done with any type of data structure.
• Example: Traversing an array, stack, queue, or linked list.
➢ Searching:
• Searching involves finding a specific element within a data
structure.
• It can be performed on arrays, linked lists, trees, graphs, etc.
• Example: Searching for an element in an array, stack, queue, or
linked list.
➢ Insertion:
• Insertion means adding an element to a data structure.
• It is a common operation across all data structures.
• Example: Adding an element to an array, stack, queue, etc.
➢ Deletion:
• Deletion involves removing data elements from a data structure.
• It can be performed on arrays, linked lists, trees, etc.
1. Abstraction:
o ADTs provide a level of abstraction by hiding the implementation
details.
o Users interact with ADTs based on what they can do (operations)
rather than how they are implemented.
o Think of ADTs as black boxes that expose essential functionality while
concealing the inner workings.
2. Essentials of ADTs:
o An ADT consists of:
▪ A set of values (the data it can hold).
▪ A set of operations (functions/methods) that can be performed
on those values.
o The ADT definition does not specify how these operations are
implemented or how data is organized in memory.
3. Examples of ADTs:
o Let’s explore a few common ADTs:
o List ADT:
▪ Represents a collection of elements (values) stored in a
sequence.
▪ Operations include:
▪ get(): Retrieve an element from any position.
▪ insert(): Add an element at any position.
▪ remove(): Remove the first occurrence of an element.
▪ size(): Get the number of elements.
▪ And more…
o Stack ADT:
▪ Follows the Last-In-First-Out (LIFO) principle.
▪ Operations include:
▪ push(): Add an element to the top.
▪ pop(): Remove the top element.
▪ isEmpty(): Check if the stack is empty.
▪ And more…
o Queue ADT:
▪ Follows the First-In-First-Out (FIFO) principle.
▪Operations include:
▪ enqueue(): Add an element to the rear.
▪ dequeue(): Remove the front element.
▪ isEmpty(): Check if the queue is empty.
▪ And more…
4. Why Use ADTs?
o ADTs provide a high-level view of data structures.
o They allow us to reason about algorithms and programs without
getting bogged down in implementation details.
o ADTs are essential for designing efficient algorithms and building
robust software systems.
Algorithms
2. Big O Notation
3. Time-Space Trade-Offs
ANS)
1. malloc() (Memory Allocation):
o The malloc() function allocates a single large block of memory with
the specified size.
o It returns a pointer of type void*, which can be cast into a pointer of
any data type.
o The allocated memory is uninitialized (contains garbage values).
o Syntax:
free(ptr);
Q-5) Discuss Recursion with Definition and Examples- Tower of Hanoi problem,
Tail Recursion.
ANS)
Recursion
❖ Program->
#include <stdio.h>
int main() {
int N = 3;
towerOfHanoi(N, 'A', 'C', 'B');
return 0;
}
❖ Output:
Tail Recursion
• Tail recursion occurs when the recursive call is the last statement executed in
a function.
• In tail recursion, there is nothing left to do after the recursive call.
• Tail-recursive functions can be optimized by compilers, as they don’t need to
maintain a separate stack frame for each recursive call.
❖ Program->
#include <stdio.h>
void print(int n) {
if (n < 0) {
return;
}
printf("%d ", n);
print(n - 1);
}
int main() {
int N = 5;
print(N);
return 0;
}
❖ Output:
ANS)
Arrays
One-Dimensional Arrays
Multidimensional Arrays
Applications of Arrays
1. Storing Data: Arrays are used to store data elements of the same type.
2. Matrices and Tables: Multidimensional arrays represent matrices, tables, and
grids.
3. Searching and Sorting: Arrays are essential for algorithms like binary search
and quicksort.
4. Dynamic Programming: Arrays are used to store intermediate results in
dynamic programming problems.
5. Graphs and Trees: Arrays can represent adjacency matrices for graphs and
trees.
Matrix Operations
• Arrays are used for matrix operations like addition, multiplication, and
transposition.
• These operations are essential in linear algebra, graphics, and scientific
computing.
Sparse Matrices
Question-1(Two Sum)
• Given an array of integer nums and an integer target, return indices of the two numbers such
that they add up to the target.
• You may assume that each input would have exactly one solution, and you may not use the
same element twice.
• You can return the answer in any order.
• Example 1:
• Input: nums = [2,7,11,15], target = 9
• Output: [0,1]
• Explanation: Because nums[0] + nums[1] == 9, we return [0, 1].
• Example 2:
• Input: nums = [3,2,4], target = 6
• Output: [1,2]
• Example 3:
• Input: nums = [3,3], target = 6
• Output: [0,1]
❖ PROGRAM:
#include <stdio.h>
#include <stdlib.h>
return arr;
}
int main() {
int nums[] = {2, 7, 11, 15};
int target = 9;
int size = sizeof(nums) / sizeof(nums[0]);
int returnSize;
int* result = twoSum(nums, size, target, &returnSize);
free(result);
return 0;
}
❖ Output:
Question-2(Remove Duplicate from Sorted array)
Given an integer array nums sorted in non-decreasing order, remove the duplicates in-place such
that each unique element appears only once. The relative order of the elements should be kept the
same. Then return the number of unique elements in nums.
Consider the number of unique elements of nums to be k, to get accepted, you need to do the
following things:
Change the array nums such that the first k elements of nums contain the unique elements in the
order they were present in nums initially. The remaining elements of nums are not important as well
as the size of nums.
Return k.
Example 1:
Explanation: Your function should return k = 2, with the first two elements of nums being 1 and 2
respectively.
It does not matter what you leave beyond the returned k (hence they are underscores).
Example 2:
Explanation: Your function should return k = 5, with the first five elements of nums being 0, 1, 2, 3,
and 4 respectively.
It does not matter what you leave beyond the returned k (hence they are underscores).
❖ Program:
#include <stdio.h>
int removeDuplicates(int nums[], int numsSize) {
if (numsSize == 0 || numsSize == 1)
return numsSize;
return j;
}
int main() {
int nums[] = {0, 0, 1, 1, 1, 2, 2, 3, 3, 4};
int numsSize = sizeof(nums) / sizeof(nums[0]);
Given a positive integer n, generate an n x n matrix filled with elements from 1 to n2 in spiral order.
Example 1:
❖ Program:
#include <stdio.h>
void generateSpiralMatrix(int n) {
int matrix[n][n];
int num = 1; // Initialize the starting number
// Move down
for (int i = rowStart; i <= rowEnd; i++) {
matrix[i][colEnd] = num++;
}
colEnd--;
// Move left
for (int i = colEnd; i >= colStart; i--) {
matrix[rowEnd][i] = num++;
}
rowEnd--;
// Move up
for (int i = rowEnd; i >= rowStart; i--) {
matrix[i][colStart] = num++;
}
colStart++;
}
int main() {
int n;
printf("Enter a positive integer n: ");
scanf("%d", &n);
generateSpiralMatrix(n);
return 0;
}
❖ Output: