Foundations of Data Structure
Foundations of Data Structure
Ans:
Time Complexity:
● Time complexity is a measure of the amount of time an algorithm takes to complete as
a function of the input size (usually denoted as n).
● It helps estimate the efficiency of an algorithm and compare it with others without
actually running the program.
Notation Examples:
●
O(1) – Constant time
●
O(n) – Linear time
●
O(n²) – Quadratic time
●
O(log n) – Logarithmic time
Example: A loop that runs n times has time complexity O(n).
Space Complexity:
● Space complexity is a measure of the amount of memory an algorithm uses during its
execution, including input storage, auxiliary space, and temporary variables.
● It tells us how efficiently an algorithm uses memory as the input size grows.
Notation Examples:
● O(1) – Constant space
● O(n) – Linear space
Example: Storing an array of n elements requires O(n) space.
Ans:
● Data structures are essential in computer science and software development.
● They provide a way to organize and manage data efficiently for different types of
operations. Here are some key applications:
Common Applications of Data Structures:
1. Databases & Operating Systems
2. Artificial Intelligence (AI) & Machine Learning (ML)
3. Computer Networks
4. Compilers and Interpreters
5. Web Browsers
6. Search Engines
7. Blockchain and Cryptography
8. Graphics and Gaming
9. File Systems
Web Browsers (Using Stack Data Structure)
Example: The "Back" and "Forward" navigation in web browsers.
● When you visit a new webpage, the current page is pushed onto a stack.
● When you click the "Back" button, the browser pops the current page from the stack
and loads the previous one.
● A second stack may be used to store "Forward" history, enabling the Forward button.
● Stack is a Last In First Out (LIFO) structure.
● Perfect for managing pages in the order they were accessed—last visited page is the
first to come back when you hit “Back”.
Ans:
1. Linear Data Structures: A linear data structure is a structure where data elements are
arranged sequentially, and each element is connected to the next and/or previous element.
Characteristics:
● Elements are stored in a single level (line).
● Easy to implement and manage.
● Memory is utilized in a sequential fashion.
Examples:
● Array , Linked List , Stack , Queue
Example: Array
Index: 0 1 2 3
Values: 5 8 12 20
Each element has a fixed position and follows a linear order.
Ans:
1. Best Case: The best case describes the minimum time or resources an algorithm will take
to complete, given the most favorable input.
● The input is in the most optimal condition.
● The algorithm finishes its task with minimum effort.
Example: Linear Search
● If you're searching for an element and it's the first item in the list:
○ Time complexity: O(1) (only one comparison).
2. Worst Case: The worst case describes the maximum time or resources an algorithm may
take, given the least favorable or most complex input.
● The input causes the algorithm to do the most work possible.
Example: Linear Search
● If the element is the last item or not present at all:
○ Time complexity: O(n) (check all elements).
(5)Explain data structure with brief introduction about primitive and Non-
primitive.
Ans:
● A data structure is a way of organizing and storing data in a computer so that it can be
used efficiently.
● It defines the relationship between data, the operations that can be performed on it,
and how data is stored and retrieved.
Types of Data Structures
1. Primitive Data Structures
● These are the basic building blocks of data manipulation, provided by most
programming languages.
Characteristics:
● Simple and predefined
● Directly operated upon by machine instructions
Examples:
● Integer (int) , Float (decimal numbers) , Character (char)
● Boolean (true/false) , Pointer
Example in C:
int age = 25;
char grade = 'A';
2. Non-Primitive Data Structures
● These are more complex and are derived from primitive data types.
● They are used to store multiple values and organize large amounts of data efficiently.
Types of Non-Primitive Data Structures:
Ans:
● An algorithm is a step-by-step, finite sequence of instructions designed to solve a
specific problem or perform a particular task.
● An algorithm is like a recipe — it tells you exactly what to do, in what order, to get
the desired result.
2. Definiteness (Clarity)
● Every step must be clear and unambiguous.
● Instructions should be precisely defined.
Not definite: “Sort the data”
Definite: “Use bubble sort to compare each pair and swap if needed”
3. Input
● An algorithm should have zero or more inputs.
● Inputs are the values supplied to the algorithm initially.
Example: Two numbers to add — a and b.
4. Output
● It must produce at least one output.
● Output is the result or solution produced by the algorithm.
Example: The sum of two numbers.
5. Effectiveness
● Each step should be simple enough to be carried out using basic operations.
● No step should require superhuman effort or infinite computation.
Example: Use basic arithmetic, not complex unknown logic.
6. Generality
● The algorithm should be applicable to a class of problems, not just one specific
instance.
Example: An algorithm to sort a list should work for any list of numbers, not just [3, 1, 4].
(7)Explain best case, worst case and average case.
Ans:
1. Best Case: The best case is the scenario where the algorithm takes the minimum possible
time or resources to complete.
Characteristics:
● Input is in the most favorable condition.
● Represents optimistic performance.
● Not reliable alone for real-world performance evaluation.
Example (Linear Search):If the element to be found is the first item in the array:
● Time Complexity: O(1)
2. Worst Case: The worst case is the scenario where the algorithm takes the maximum
possible time or resources to complete.
Characteristics:
● Input is in the least favorable condition.
● Represents the maximum workload for the algorithm.
● Useful for performance guarantees.
Example (Linear Search): If the element is the last item or not present at all:
● Time Complexity: O(n)
3. Average Case: The average case represents the algorithm's performance on typical or
random inputs.
Characteristics:
● Calculates the expected time taken over all possible inputs.
● More realistic measure than best or worst case.
● Often requires probability analysis.
Example (Linear Search): If the element is equally likely to be anywhere in the array:
● Average Time Complexity: O(n/2) → simplified to O(n)
(8)Differentiate primitive and non-primitive data structures
Ans:
Simple and easy to use Complex and used to store large or related
data
Examples: int, char, float, boolean Examples: Array, List, Stack, Queue, Tree,
Graph
Basic operations (arithmetic, logical, etc.) Various operations (insert, delete, search,
sort, etc.)
Ans:
#include <stdio.h> //Includes the Standard Input/Output library. Needed for
functions like printf() and scanf()
int binarySearch(int arr[], int size, int target) { //Declares a function named
binarySearch.
● It takes:
○ arr[]: the sorted array,
○ size: number of elements in the array,
○ target: the number to search for.
int low = 0; //Sets the starting index of the search to the first element of the array.
int high = size - 1; //Sets the end index of the search to the last element of the array.
while (low <= high) { //Loop runs as long as there are elements to check (i.e.,
valid search range). If low > high, the search ends (element not found).
int mid = (low + high) / 2; //Finds the middle index between low and high.
return mid;
}
else if (arr[mid] < target) { //If the target is greater than the middle element, It
means the target must be in the right half, so we set: low = mid + 1
low = mid + 1;
} // If target is smaller, ignore the right half
else { //else
● If the target is less than the middle element,
● It must be in the left half, so we set: high = mid - 1
high = mid - 1;
}
}
return -1; // If the loop finishes without finding the target, return -1 to indicate
not found.
}
int main() { //The main function where the program starts execution.
int arr[] = {2, 4, 10, 15, 20, 25, 30}; // Declares and initializes a sorted array of
integers.
int target; //Declares a variable to store the number the user wants to search.
printf("Enter the number to search: "); //Asks the user to enter a number.
scanf("%d", &target); //Takes user input and stores it in the target variable.
if (result != -1) { //If the result is not -1, that means the element was found.
printf("Element found at index %d\n", result); //Prints the index where the
element was found.
} else {
printf("Element not found in the array.\n"); //If the result is -1, it means the
element isn't in the array.
Sample Output:
Enter the number to search: 20
Element found at index 4
Ans:
● An algorithm is a step-by-step procedure used to solve a problem or perform a task.
● For any set of instructions to be considered a valid algorithm, it must have certain key
features.
2. Output
● The algorithm should produce at least one output.
● The output is the result or solution of the problem.
Example: After adding two numbers, the result (sum) is the output.
3. Finiteness
● The algorithm must end after a finite number of steps.
● If an algorithm runs forever, it's not useful.
Example: A loop that runs exactly 10 times is finite; a loop without an exit condition is not.
4. Definiteness (Clarity)
● Each step of the algorithm must be clear, exact, and unambiguous.
● Ambiguity can lead to confusion or errors during execution.
Bad instruction: “Do the next step properly.”
Good instruction: “Add 5 to the current number.”
5. Effectiveness
● All operations must be basic enough to be done in a reasonable time using available
resources.
● Steps should be practical and doable — not just theoretical.
Example: Adding two numbers is effective; solving a puzzle by guessing infinitely is not.
6. Generality
● The algorithm should work for a range of inputs, not just one specific case.
● A good algorithm can solve many similar problems, not just one.
Example: A sorting algorithm should work for any list of numbers, not just one list.
Ans:
● In call by value, a copy of the actual argument is passed to the function.
● Changes made inside the function do not affect the original variables.
void swap(int a, int b) { //Declares a function named swap that takes two integers
as input.These are copies of the actual values passed (call by value).
int main() { //Entry point of the program. The main() function starts the
execution.
int x = 10, y = 20; //Declares and initializes two integers x and y.
swap(x, y); //Calls the swap function and passes copies of x and y.
Inside the function, a = x and b = y, but changes to a and b don’t affect x and y.
printf("x = %d, y = %d\n", x, y); //Prints the values of x and y again, showing
that they are unchanged.
Output:
Before calling swap:
x = 10, y = 20
Inside swap function:
a = 20, b = 10
After calling swap:
x = 10, y = 20
Explanation:
● swap(x, y) passes copies of x and y to the function.
● Inside swap, the values are swapped, but the original variables in main() remain
unchanged.
● This shows how call by value works — it does not affect the original variables.
(12) What is string? What are the common operations performed on string?
Ans:
● A string is a sequence of characters used to represent text.
● In C and many other languages, a string is an array of characters that ends with a null
character ('\0').
Example of a String in C:
char name[] = "Akash";
Behind the scenes, it is stored as:
A k a s h \0
Common Operations Performed on Strings
1. Finding the Length of a String
● Use: To count the number of characters (excluding \0)
● Function in C: strlen()
Example:
int len = strlen("Hello"); // len = 5
6.Converting Case
● Use: To convert string to uppercase/lowercase
● Functions (not standard C, available in <ctype.h> with loops):
○ toupper(), tolower() (used character by character)
7. Reversing a String
● Use: To get the reverse of the original string
● No built-in function in C; typically done with a loop.
Ans:
1. String Constant:
● A string constant, also called a string literal, is a fixed sequence of characters enclosed
in double quotes (").
● A string constant is a read-only text value written directly in the code, automatically
ending with a null character \0.
Examples:
"Hello"
"123"
"Welcome to C!"
""
Stored as:
The string "Hello" is stored in memory like this:
H e l l o \0
Properties:
● Immutable (read-only in many cases)
● Automatically null-terminated
● Stored in a fixed memory location (usually in read-only segment)
int main() { //The main function where the program starts running.
char str2[20]; //Declares a second character array named str2. It can hold up to
19 characters + 1 null character. No initial value is assigned here.
strcpy(str2, "World"); //Copies the string "World" into str2. After this line, str2
contains: "World".
strcat(str1, " "); //Appends a space (" ") to the end of str1. So now str1 becomes
"Hello ".
strcat(str1, str2); // Appends the contents of str2 (which is "World") to the end
of str1. Now str1 becomes "Hello World".
printf("Result: %s\n", str1); //Prints the final content of str1. %s is the format
specifier for strings.
Output: Result: Hello World
Output:
Result: Hello World
(15) Explain STR_CAT() in brief with algorithm
Ans:
● strcat() is a standard library function in C used to concatenate (join) two strings.
● It appends the second string at the end of the first string.
Header File:
#include <string.h>
Syntax:
char *strcat(char *destination, const char *source);
● destination – the string where the second string (source) will be added.
● source – the string to be appended.
● The destination string must have enough space to hold the final combined result.
Example:
char str1[20] = "Hello ";
char str2[] = "World";
Ans:
● STR_TOLOWER() refers to converting all uppercase letters in a string to their
lowercase equivalents.
● It’s commonly implemented using the tolower() function from C’s <ctype.h> library
applied to each character in a string.
Header File in C:
#include <ctype.h>
Example Code in C:
#include <stdio.h>
#include <ctype.h> // for tolower()
int main() {
char text[] = "HeLLo WoRLD!";
str_to_lower(text);
Ans:
● STR_REV() refers to a string reversal operation — it takes a string and reverses the
order of its characters.
For example:
Input: "hello"
Output: "olleh"
Purpose: To reverse the characters in a string in place (without creating a new string), or by
storing the reversed string into another variable.
Step-by-Step: Algorithm STR_REV(string)
1. Start
2. Initialize two variables:
- left = 0 (start of string)
- right = length of string - 1 (end of string)
3. While left < right:
a. Swap string[left] and string[right]
b. Increment left by 1
c. Decrement right by 1
4. End
Key Idea: Swap characters from the two ends, moving toward the middle, until they meet.
Example (Dry Run):
Input: "ABCD"
● Swap A and D → DBCA
● Swap B and C → DCBA
Output: "DCBA"
C Code Example:
#include <stdio.h>
#include <string.h>
// Move pointers
left++;
right--;
}
}
int main() {
char text[] = "hello";
str_rev(text);
return 0;
}
Output:
Reversed string: olleh
Key Notes:
● Works for any string stored in a character array.
● Doesn’t use any built-in reverse function — only logic and swapping.
● You must make sure the input string is null-terminated (\0).
(18) Explain STR_COPY() in brief with algorithm
Ans:
● STR_COPY() refers to the process of copying one string into another.
● It is similar to the standard C function: strcpy(destination, source);
Purpose: To copy each character from the source string to the destination string, including
the null character \0 that marks the end of the string.
Step-by-Step Algorithm: Algorithm STR_COPY(destination, source)
1. Start
2. Initialize index i = 0
3. Repeat until source[i] == '\0':
a. Set destination[i] = source[i]
b. Increment i by 1
4. After the loop, set destination[i] = '\0' // to terminate the string
5. End
Key Idea: Copy all characters from the source to destination, one by one, including the null
terminator.
C Code Example:
#include <stdio.h>
void str_copy(char dest[], const char src[]) {
int i = 0;
int main() {
char source[] = "OpenAI";
char destination[20]; // Make sure it's big enough
str_copy(destination, source);
return 0;
}
Output:
Copied string: OpenAI
Key Notes:
● The destination array must be large enough to hold all characters from the source
string including the \0.
● You must terminate the copied string with '\0' to mark the end.
● This logic is similar to how strcpy() works internally in C.
Ans:
● Pattern matching is a common problem in computer science where we try to find a
smaller string (called a pattern) inside a larger string (called the text).
Goal of Pattern Matching Algorithm
Given:
● A text of length n
● A pattern of length m
Find whether the pattern occurs in the text, and if so, at which position(s).
Assumptions
We’ll use the Naive (brute-force) pattern matching algorithm, which is the simplest.
Step-by-Step: Algorithm PATTERN_MATCH(text, pattern)
1. Start
2. Let n = length of text
3. Let m = length of pattern
4. For i from 0 to (n - m):
a. Initialize match = true
b. For j from 0 to (m - 1):
i. If text[i + j] ≠ pattern[j], then:
- Set match = false
- Break inner loop
c. If match == true:
- Print "Pattern found at position i"
5. End
Example
Text: "abcabcabc"
Pattern: "cab"
Dry Run:
● At index 0: "abc" ≠ "cab"
✅ Match at index 2
● At index 1: "bca" ≠ "cab"
● At index 2: "cab" == "cab" →
C-style Pseudocode
for (i = 0; i <= n - m; i++) {
match = 1;
for (j = 0; j < m; j++) {
if (text[i + j] != pattern[j]) {
match = 0;
break;
}
}
if (match) {
printf("Pattern found at position %d", i);
}
}
Time Complexity
● Worst-case: O(n × m)
(when we compare the pattern at every position)
Advanced Alternatives:
● KMP Algorithm (Knuth-Morris-Pratt) → O(n + m)
● Rabin-Karp Algorithm
● Boyer-Moore Algorithm
Ans:
● In C and many programming languages, strings are arrays of characters ending with a
special null character ('\0').
● The string length is the number of characters before the '\0'.
For example: "hello" → length = 5
Step-by-Step Algorithm: Algorithm STRING_LENGTH(str)
1. Start
2. Initialize a counter variable: length = 0
3. While str[length] ≠ '\0':
a. Increment length by 1
4. End While
5. Return length
6. End
Explanation:
● Start at the first character.
● Keep counting until you hit the null character ('\0').
● The value of the counter is the string’s length.
Example (Dry Run)
Input: "cat\0"
Steps:
● str[0] = 'c' → count = 1
● str[1] = 'a' → count = 2
● str[2] = 't' → count = 3
● str[3] = '\0' → stop
→ Output: 3
C-style Pseudocode
int string_length(char str[]) {
int length = 0;
return length;
}
Explanation:
● Use two loops:
○ The outer loop sets the starting point of the substring.
○ The inner loop sets the ending point.
● Print all characters from the starting to the ending index.
Example:
Input: "abc"
Substrings:
"a" (i=0, j=0)
"ab" (i=0, j=1)
"abc" (i=0, j=2)
"b" (i=1, j=1)
"bc" (i=1, j=2)
"c" (i=2, j=2)
C-style Pseudocode:
void find_substrings(char str[]) {
int i, j, k;
int len = strlen(str);
char sub[100];
Time Complexity:
● O(n²) substrings
● O(n³) total time if you print each character individually
(22) Convert infix expression into Prefix/Postfix format showing stack
status after every step in tabular form.
a. (A + B) * C – D * E * (F * G)
b. (A+B)*D+E/(F+G*D)+C
c. A/B$C+D*E/F-G+H
d. A – B / C * D + E * F / G
e. (( A –( B +C))* D) $ ( E + F )
Ans:
1. Infix → Postfix
Key Rules:
1. Read tokens left to right.
2. Operands → output.
3. Operators → push onto stack based on precedence and associativity.
4. '(' → push onto stack.
5. ')' → pop operators to output until '(' is found and discarded.
6. After input ends, pop remaining operators to output.
2. Infix → Prefix
Key Steps:
1. One stack for operators, another for operands.
2. For each token:
○ If '(': push to operators.
○ If operand: push to operands stack.
○ If operator: pop higher-or-equal precedence operators, combine top two
operands (op + op1 + op2), push result back; then push current operator.
○ If ')': pop until '(', combining operands similarly.
3. After reading input, apply remaining operators to operands to get final prefix.
a. (A + B) * C – D * E * (F * G)
Part 1: Convert to Postfix
Expression: (A + B) * C – D * E * (F * G)
● (A + B) → inside parentheses, convert A + B to postfix → A B +
● * C → multiply with C → postfix becomes A B + C *
● Then – D * E * (F * G)
Break down:
○ D * E → D E *
○ (F * G) → F G *
○ D * E * (F * G) → D E * F G * *
● Now, subtract A B + C * and D E * F G * *
So postfix becomes: A B + C * D E * F G * * -
Final postfix: A B + C * D E * F G * * -
Part 2: Convert to Prefix
Using the reverse method:
Step 1: Reverse the infix expression and swap parentheses
Original: (A + B) * C – D * E * (F * G)
Reverse: ) G * F ( * E * D – C * ) B + A (
Swap ( and ): ( G * F ) * E * D – C * ( B + A )
Reverse: - * + A B C * D * E * F G
Final prefix: - * + A B C * D * E * F G
b. (A+B)*D+E/(F+G*D)+C
Part 1: Convert to Postfix
Expression: (A + B) * D + E / (F + G * D) + C
Breakdown:
1. (A + B) → postfix: A B +
2. (A + B) * D → postfix: A B + D *
3. (F + G * D) →
○ G * D → G D *
○ F + (G D *) → F G D * +
4. E / (F + G * D) → postfix: E F G D * + /
5. (A + B) * D + E / (F + G * D) → postfix: A B + D * E F G D * + / +
6. Add + C → postfix: A B + D * E F G D * + / + C +
Final Postfix: A B + D * E F G D * + / + C +
Part 2: Convert to Prefix
Using the reverse method:
Step 1: Reverse the infix and swap parentheses
Original: (A + B) * D + E / (F + G * D) + C
Reverse: C + ) D * G + F ( / E + D * ) B + A (
Swap ( and ): C + ( D * G + F ) / E + D * ( B + A )
Convert stepwise:
● (D G * F +) / E → D G * F + E /
● D * (B A +) → D B A + *
● Now the full expression: C + (D G * F + E /) + (D B A + *)
● Convert (C + ...) + ... → C (D G * F + E /) + (D B A + *) +
Reverse tokens: + * A B D + / E + F * G D C
So prefix: + * + A B D + / E + F * G D C
Final Prefix: + + * + A B D / E + F * G D C
c. A / B $ C + D * E / F - G + H
Current output: A B C $ /
Stack: +
7. D → operand → output: D
8. * → operator →
○ * has higher precedence than +, push *
9. E → operand → output: E
10./ → operator →
○ / has equal precedence to * and left-associative → pop * → output *
○ Push /
11.F → operand → output: F
12.- → operator →
○ Stack: + (bottom), / (top)
○ / has higher precedence than -, pop / → output /
○ + has equal precedence to -, pop + → output +
○ Push -
13.G → operand → output: G
14.+ → operator →
○ - has equal precedence to +, pop - → output -
○ Push +
15.H → operand → output: H
No parentheses to swap.
Operators:
● $ highest precedence, right-associative
● *, / medium, left-associative
● +, - lowest, left-associative
Reversed tokens: + / A $ B C - * D / E F + G H
Final Prefix: + / A $ B C - * D / E F + G H
d. A – B / C * D + E * F / G
Output steps:
● Operands: A B C / D * - E F * G / +
Final Postfix: A B C / D * - E F * G / +
e. ( ( A – ( B + C ) ) * D ) $ ( E + F )
Final Prefix: $ * - A + B C D + E F
(23) Write and explain the POP operation algorithm of a stack.
Assumptions:
● The stack is implemented using an array (or list).
● top is an integer variable indicating the current top position in the stack.
● stack is the array holding the elements.
Algorithm (Pseudo-code):
POP(stack):
if top == -1 then // stack is empty (underflow)
print "Stack Underflow"
return ERROR // or appropriate error value
else
element = stack[top] // get the top element
top = top - 1 // decrement top to remove the element
return element // return the popped element
Explanation:
1. Check if stack is empty: If top is -1 (or some value indicating empty), the stack is
empty, so POP cannot remove any element. This is called stack underflow.
2. Retrieve the element: The element at stack[top] is the current top of the stack.
3. Update the top: Decrement top by 1 to reflect the removal of the top element.
4. Return the popped element: The element removed from the stack is returned to the
caller.
Example:
If stack = [10, 20, 30, 40] and top = 3 (pointing to 40), after POP(stack),
● The function returns 40,
● And the top becomes 2, so the new top is 30.
(24) Write and explain the PUSH operation algorithm of a stack.
Ans:
PUSH Operation
● To add (push) an element to the top of the stack.
● Handle stack overflow when the stack is full.
Assumptions:
● stack is an array of size MAX.
● top points to the current top index; -1 means empty.
Algorithm (Pseudo-code):
PUSH(stack, element):
if top == MAX - 1 then // stack is full
print "Stack Overflow"
return ERROR
else
top = top + 1 // increment top
stack[top] = element // place new element
Explanation:
1. Check if the stack is full (top == MAX - 1).
2. If full, report overflow and stop.
3. Otherwise, increase top and place the new element at stack[top].
Ans:
1. Solving Math Expressions
● Stacks help change math problems from normal form (like A + B) into easier forms to
calculate, and also help do the calculations step-by-step.
7. Managing Memory
● Stacks help the computer organize memory by adding and removing things in order.
Ans:
● A pointer is a special variable that stores the address of another variable in memory
instead of the actual data.
Why use pointers?
● To directly access or modify variables in memory.
● To work efficiently with arrays, strings, and dynamic memory.
● To pass large data structures to functions without copying.
Example in C:
int x = 10; // A normal integer variable
int *p; // A pointer to an integer
Explanation:
● int *p; declares a pointer to an integer.
● p = &x; assigns the address of x to the pointer p.
● *p means "value at the address stored in p" — so *p is the value of x.
● This allows us to access or change x using the pointer.
Ans:
Advantages of Pointers Disadvantages of Pointers
Efficient direct access to memory locations Can be complex and hard to understand
Allow dynamic memory allocation and Risk of errors like segmentation faults and
deallocation leaks
Enable passing large data to functions Can cause security vulnerabilities if misused
without copying
Simplify array and string manipulation via Dangling or null pointers can cause
pointer arithmetic undefined behavior
(28) Difference between static memory allocation and dynamic memory
allocation
Ans:
Static Memory Allocation Dynamic Memory Allocation
Memory is Allocated At compile time Memory is Allocated At runtime
Fixed size, determined before program runs Size can change during program execution
Memory Lifetime Exists throughout the Memory Lifetime Exists until explicitly
program execution freed by the program
Examples: Global variables, static variables, Examples: Memory allocated using malloc,
local variables inside functions calloc, realloc in C
Risk of Errors: Less prone to memory leaks Risk of Errors: Can cause memory leaks or
dangling pointers if not managed properly
Ans:
Linked List Sequential List (Array)
Memory Allocation Dynamic Memory Allocation Static
Can easily grow by adding/removing nodes Size is fixed (unless dynamically resized)
Sequential access; no direct access to Direct access to any element using index
elements (O(1))
Uses extra memory for storing pointers Uses memory only for data elements
Poorer cache locality due to scattered Better cache locality due to contiguous
memory storage