Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
0% found this document useful (0 votes)
2 views

Data Structure

The document discusses the importance of studying data structures for efficient software development, detailing major data structures used in RDBMS, network, and hierarchical data models. It also covers various algorithms and concepts such as graph representation, binary search trees, garbage collection, characteristics of good algorithms, dynamic storage management in C, and queue implementation using singly linked lists. Additionally, it provides examples and code snippets for better understanding.

Uploaded by

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

Data Structure

The document discusses the importance of studying data structures for efficient software development, detailing major data structures used in RDBMS, network, and hierarchical data models. It also covers various algorithms and concepts such as graph representation, binary search trees, garbage collection, characteristics of good algorithms, dynamic storage management in C, and queue implementation using singly linked lists. Additionally, it provides examples and code snippets for better understanding.

Uploaded by

Arshiyan Sayyad
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 20

Data structure 2

Q.1 Why to study data structures ? What are the major data structure used in the RDBMS, network
and hierarchical data model.

Ans:- Why Study Data Structures?

Studying data structures is essential because they are the foundation of efficient software
development. They help in:

1. Efficient Data Storage & Retrieval – Optimized storage and access to data.
2. Improved Algorithm Performance – Better performance and reduced complexity.
3. Scalability – Handling large datasets efficiently.
4. Memory Optimization – Managing memory effectively.
5. Problem Solving – Many real-world problems are easier to solve with proper data
structures.
6. Software Development & System Design – Used in databases, operating systems,
AI, and more.

Major Data Structures Used in Different Models

1. Relational Database Management System (RDBMS)

RDBMS organizes data in tables with predefined schemas. The major data structures used
include:

 Arrays – Used for indexing and temporary storage.


 Linked Lists – Used in query execution plans.
 Hash Tables – Used for indexing (e.g., hash indexing in PostgreSQL).
 B-Trees & B+ Trees – Used for efficient indexing and searching.
 Graphs – Used in SQL joins and relationships.

2. Network Data Model

Network databases use a graph-like structure with records connected by links. Major data
structures used:

 Graphs (Directed) – Nodes (records) connected with edges (pointers).


 Adjacency List / Matrix – To represent relationships.
 Hash Tables – To quickly access data via keys.

3. Hierarchical Data Model

Hierarchical databases follow a tree structure (like XML, LDAP). Major data structures
used:

 Trees (Binary, n-ary) – Parent-child relationships.


 Linked Lists – Used for navigating hierarchical relationships.
 Stacks – Used in traversal operations (e.g., depth-first search).
Q.2Consider the following specification of a graph G=(V,E)G = (V, E)G=(V,E):

 Vertices (V): {1,2,3,4}


 Edges (E): {(1,2),(1,3),(3,3),(3,4),(4,1)}
  Draw an undirected graph for the given specification.
  Represent graph GGG using an adjacency matrix.
  Represent graph GGG using an adjacency linked list.

Ans:- Step 1: Drawing the Undirected Graph

The given edges define the connections between vertices:

 (1,2) → Edge between 1 and 2


 (1,3) → Edge between 1 and 3
 (3,3) → Self-loop on vertex 3
 (3,4) → Edge between 3 and 4
 (4,1) → Edge between 4 and 1

Graph representation

1 ---- 2

|\

| \

4 -- 3

⤸ (Self-loop) Step 2: Adjacency Matrix Representation

An adjacency matrix is a 4×44 matrix where:

 If there is an edge between two vertices i and j, then M[i][j]=1, otherwise 0.


 Since it's undirected, the matrix is symmetric.
 A self-loop (e.g., (3,3)) is represented as 1 in M[3][3]

0111

1000

1011

1010

Step 3: Adjacency List Representation

Each vertex stores a list of its connected vertices.

1→2→3→4

2→1
3→1→3→4

4→1→3

Q.3Suppose the numbers: 50,15,62,5,20,58,91,3,8,37,60,24 are inserted in order into an initially


empty binary search tree . what is preorder, inorder and postorder traversal sequence of the tree ?

Ans:- Given sequence:


50, 15, 62, 5, 20, 58, 91, 3, 8, 37, 60, 24

Step 1: Constructing the BST

1. Insert 50 → Root node.


2. Insert 15 → Left of 50.
3. Insert 62 → Right of 50.
4. Insert 5 → Left of 15.
5. Insert 20 → Right of 15.
6. Insert 58 → Left of 62.
7. Insert 91 → Right of 62.
8. Insert 3 → Left of 5.
9. Insert 8 → Right of 5.
10. Insert 37 → Right of 20.
11. Insert 60 → Right of 58.
12. Insert 24 → Left of 37.

Step 2: The BST Structure


markdown

50
/ \
15 62
/ \ / \
5 20 58 91
/ \ \ /
3 8 37 60
/
24

Step 3: Traversal Orders

1. Inorder Traversal (Left → Root → Right)

Inorder: 3, 5, 8, 15, 20, 24, 37, 50, 58, 60, 62, 91

2. Preorder Traversal (Root → Left → Right)

Preorder: 50, 15, 5, 3, 8, 20, 37, 24, 62, 58, 60, 91


3. Postorder Traversal (Left → Right → Root)

Postorder: 3, 8, 5, 24, 37, 20, 15, 60, 58, 91, 62, 50

Q.4 What is garbage collection ? who will run garbej collection program ? when it will be run ?

Ans:- What is Garbage Collection?

Garbage Collection (GC) is the process of automatically identifying and reclaiming


unused memory in a program. It helps prevent memory leaks by removing objects that are
no longer accessible, freeing up memory for new allocations.

Who Runs the Garbage Collection Program?

Garbage Collection is managed by the runtime environment of programming languages that


support automatic memory management.

 Java → JVM (Java Virtual Machine)


 C# → .NET CLR (Common Language Runtime)
 Python → Python Garbage Collector (part of the interpreter)
 JavaScript → JavaScript Engine (V8, SpiderMonkey, etc.)

In languages like C and C++, memory management is manual, meaning developers must
allocate (malloc/new) and deallocate (free/delete) memory themselves.

When is Garbage Collection Run?

Garbage Collection runs automatically, but the exact timing depends on the language and
implementation:

1. Memory Threshold Reached → When allocated memory exceeds a certain limit.


2. Idle CPU Time → Some GC algorithms run when the processor is idle.
3. Explicit Request → Some languages allow manual triggering:
o Java → System.gc() (only suggests GC, not guaranteed).
o Python → gc.collect() (forces collection).

Types of Garbage Collection Algorithms

 Reference Counting → Tracks the number of references to an object.


 Mark and Sweep → Marks reachable objects and sweeps unreferenced ones.
 Generational GC → Divides memory into young and old generations for optimization.
 Copying GC → Copies live objects to a new space and deletes everything else.
Q.5 Give the characteristics of good algorithm. Also explain how do we analyse the algorithm.

Ans:- Characteristics of a Good Algorithm

A good algorithm should have the following key characteristics:

1. Correctness – It should produce the correct output for all valid inputs.
2. Efficiency – It should be optimized in terms of time complexity and space complexity.
3. Finiteness – It should terminate after a finite number of steps.
4. Definiteness – Every step should be well-defined and clear.
5. Input & Output – It should take valid inputs and generate expected outputs.
6. Generality – It should be applicable to different problem instances, not just a specific case.
7. Simplicity & Maintainability – The algorithm should be easy to understand and modify.

How to Analyze an Algorithm?

Algorithm analysis helps determine its performance and efficiency in terms of time and
space complexity.

1. Time Complexity Analysis

 Measures how execution time increases as input size grows.


 Expressed using Big-O notation (O(n), O(log n), etc.).
 Categories:
o Best Case → Minimum time required.
o Average Case → Expected time for random inputs.
o Worst Case → Maximum time required.

Examples of Time Complexities

Complexity Example algorithm


O(1) Accessing an array element
O(log n) Binary search
O(n) Linear search
O(n log n) Merge sort, Quick sort (average case)
O(n2) Bubble sort, Insertion sort
O(2ⁿ) Recursive Fibonacci
O(n!) Traveling Salesman Problem (Brute Force)

2. Space Complexity Analysis

 Measures the amount of memory an algorithm needs.


 Includes:
o Fixed part → Constants, variables, program instructions.
o Variable part → Memory for dynamic structures (e.g., recursion stack, arrays).

Examples of Space Complexities


Complexity Example Algorithm
O(1) Variables, pointers
O(n) Arrays, linked lists
O(n²) 2D matrices, dynamic programming
3. Asymptotic Notations (Used for Analysis)

 Big-O (O) → Upper bound (worst case).


 Theta (Θ) → Tight bound (average case).
 Omega (Ω) → Lower bound (best case).

Q.6a) What is a Sparse Matrix? Convert the following sparse matrix into a non-sparse
matrix 1 0 0 0

Ans:- a) What is a Sparse Matrix?

A sparse matrix is a matrix that has a majority of its elements as zero. It is stored
efficiently using techniques such as compressed row storage (CRS), linked lists, or
coordinate lists, reducing memory usage and improving performance in certain
computations.

b) Conversion of Sparse Matrix to Non-Sparse Matrix

A non-sparse matrix (or dense matrix) should contain meaningful values replacing the zero
elements. Since the given matrix contains mostly zeros, we need to replace zeros with
meaningful values based on the problem context.

Example of a possible non-sparse matrix (if replacing zeros with small random values):

1 2 3 4

or

1 1 1 1

or

sql
1 X X X (where X represents relevant nonzero values)

Q.7 Write a short note on dynamic storage management . Explain how it is done in C.

Ans:- Short Note on Dynamic Storage Management

Dynamic Storage Management refers to the process of allocating and deallocating


memory at runtime as needed, rather than at compile-time. It allows efficient use of
memory by providing flexibility in handling variable-sized data structures such as linked
lists, trees, and dynamic arrays.
Dynamic Memory Management in C

C provides four standard library functions for dynamic memory management, available in the
<stdlib.h> library:

1. malloc(size) → Allocates a block of memory but does not initialize it.


2. calloc(n, size) → Allocates memory for an array of n elements and initializes them to
zero.
3. realloc(ptr, new_size) → Resizes a previously allocated memory block.
4. free(ptr) → Deallocates previously allocated memory.

#include <stdio.h>
#include <stdlib.h>
int main() {
int *ptr;
// Allocate memory for 5 integers
ptr = (int*) malloc(5 * sizeof(int));
if (ptr == NULL) {
printf("Memory allocation failed!\n");
return 1;
}
// Initialize and print values
for (int i = 0; i < 5; i++) {
ptr[i] = i + 1;
printf("%d ", ptr[i]);
}
// Free allocated memory
free(ptr);
return 0;
}

Key Points:

 Heap memory is used for dynamic allocation.


 Always free allocated memory to prevent memory leaks.
 malloc() and realloc() do not initialize memory, while calloc() does.
 free() does not reset pointer value (use ptr = NULL after freeing).
Q.8 Consider a stack with N = 6 memory cells allocated. Initially, the stack contains:
A, D, E, F, G (Top of Stack).

Perform the following operations in order, updating the stack accordingly:


i) Push(stack, K)
ii) Pop(stack, Item)
iii) Push(stack, L)
iv) Push(stack, S)
v) Pop(stack, Item)
vi) Push(stack, T)

Ans:-

Initial Stack State:

Bottom → [A, D, E, F, G,] ← Top

Step-by-Step Execution:

1 Push(stack, K) → Add K to the stack.

Bottom → [A, D, E, F, G, K] ← Top

✅ Successful (Stack is now full)

2 Pop(stack, Item) → Remove the top item (K).

Bottom → [A, D, E, F, G] ← Top

✅ Popped Item: K

3 Push(stack, L) → Add L to the stack.

Bottom → [A, D, E, F, G, L] ← Top

✅ Successful

4 Push(stack, S) → Stack is full, so we get Stack Overflow. ✅

5 Pop(stack, Item) → Remove the top item (L).

Bottom → [A, D, E, F, G] ← Top

✅ Popped Item: L

6 Push(stack, T) → Add T to the stack.

Bottom → [A, D, E, F, G, T] ← Top


✅ Successful
Final Stack State:
Bottom → [A, D, E, F, G, T] ← Top

Situations Encountered:

✅ Successful Operations: Push(K), Pop(K), Push(L), Pop(L), Push(T).


✅ Stack Overflow at Push(S) (Stack was full).

Q.9What is queue? Write an algorithm to implement insert item into queue using singly
linked list?

Ans:-

What is a Queue?

A queue is a linear data structure that follows the FIFO (First In, First Out) principle.

 Enqueue (Insertion): Adds an element to the rear of the queue.


 Dequeue (Deletion): Removes an element from the front of the queue.

Types of Queues:

1. Simple Queue – Follows FIFO.


2. Circular Queue – Connects the last node back to the first.
3. Priority Queue – Elements are dequeued based on priority.
4. Double-Ended Queue (Deque) – Insertion and deletion from both ends.

Algorithm to Insert (Enqueue) an Item into a Queue Using


a Singly Linked List
Node Structure:

Each node contains:

1. data – The value to be stored.


2. next – Pointer to the next node.

Algorithm (Enqueue Operation)

1. Create a new node with the given value.


2. If the queue is empty, set both front and rear to this new node.
3. Otherwise, set the next of the current rear to the new node.
4. Update rear to point to the new node.
5. End.

C Implementation:
CopyEdit
#include <stdio.h>
#include <stdlib.h>

// Define a structure for the queue node


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

// Define the front and rear of the queue


struct Node* front = NULL;
struct Node* rear = NULL;

// Function to insert an element into the queue


void enqueue(int value) {
// Create a new node
struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
if (newNode == NULL) {
printf("Memory allocation failed!\n");
return;
}
newNode->data = value;
newNode->next = NULL;

// If the queue is empty, set front and rear to new node


if (rear == NULL) {
front = rear = newNode;
} else {
// Attach new node to the end and update rear
rear->next = newNode;
rear = newNode;
}
printf("Inserted: %d\n", value);
}

// Function to display the queue


void display() {
struct Node* temp = front;
if (front == NULL) {
printf("Queue is empty!\n");
return;
}
printf("Queue: ");
while (temp != NULL) {
printf("%d -> ", temp->data);
temp = temp->next;
}
printf("NULL\n");
}

// Main function to test the queue


int main() {
enqueue(10);
enqueue(20);
enqueue(30);
display(); // Output: 10 -> 20 -> 30 -> NULL

return 0;
}
Time Complexity:

 Insertion (Enqueue): O(1) (constant time, as we insert at the rear).


 Deletion (Dequeue, if implemented): O(1) (rem

Q.10 Write an algorithm to evaluate postfix expression using stack and execute your
algorithm with postfix expression 10,5,6,*,+,8,/. Show intermediate stack content after each
operation ?

Ans:- Algorithm to Evaluate a Postfix Expression Using a Stack

Steps:

1. Create an empty stack.


2. Scan the postfix expression from left to right.
3. For each token in the expression:
o If the token is an operand (number), push it onto the stack.
o If the token is an operator (+, -, *, /, etc.):
1. Pop the top two elements from the stack.
2. Perform the operation.
3. Push the result back onto the stack.
4. After scanning all tokens, the final result will be at the top of the stack.

Execution of Algorithm with Postfix Expression:


Expression: 10 5 6 * + 8 /

(Equivalent Infix: (10 + (5 * 6)) / 8)

Step-by-Step Stack Operations:

Step Symbol Stack Content (Top → Bottom) Operation Performed


1 10 10 Push 10
2 5 5,10
3 6 6, 5, 10 Push 6
4 * 30, 10 Pop 6 and 5, Compute 5 * 6 = 30, Push 30
5 + 40 Pop 30 and 10, Compute 10 + 30 = 40, Push 40
6 8 8, 40 Push 8
7 / 5 Pop 40 and 8, Compute 40 / 8 = 5, Push 5

Final Result: 5

C Implementation:

#include <stdio.h>

#include <stdlib.h>
#include <ctype.h>

#define MAX 100

// Stack structure

struct Stack {

int top;

float items[MAX];

};

// Function to initialize stack

void initStack(struct Stack* s) {

s->top = -1;

// Function to check if stack is empty

int isEmpty(struct Stack* s) {

return (s->top == -1);

// Function to push an element onto stack

void push(struct Stack* s, float value) {

if (s->top == MAX - 1) {

printf("Stack Overflow!\n");

return;

s->items[++s->top] = value;

}
// Function to pop an element from stack

float pop(struct Stack* s) {

if (isEmpty(s)) {

printf("Stack Underflow!\n");

exit(1);

return s->items[s->top--];

// Function to evaluate a postfix expression

float evaluatePostfix(char* expression[]) {

struct Stack stack;

initStack(&stack);

for (int i = 0; expression[i] != NULL; i++) {

char* token = expression[i];

// If the token is an operand, push it to the stack

if (isdigit(token[0])) {

push(&stack, atof(token));

} else {

// Pop two operands

float val2 = pop(&stack);

float val1 = pop(&stack);

// Perform the operation

switch (token[0]) {
case '+': push(&stack, val1 + val2); break;

case '-': push(&stack, val1 - val2); break;

case '*': push(&stack, val1 * val2); break;

case '/': push(&stack, val1 / val2); break;

return pop(&stack);

// Driver Code

int main() {

char* postfix[] = {"10", "5", "6", "*", "+", "8", "/", NULL};

printf("Result: %.2f\n", evaluatePostfix(postfix));

return 0;

Final Notes:

 The algorithm correctly follows LIFO (Last In, First Out) order of the stack.
 It handles multiple operators in left-to-right order.
 Time Complexity: O(n) (linear traversal of expression).
 Space Complexity: O(n) (due to stack usage).
Q.11Store the elements of the given binary tree using:

1. One-dimensional array representation


2. Linked list representation

/\

b c

/\ \

d e f

Ans:- 1. One-Dimensional Array Representation

A binary tree can be stored in an array using level-order indexing (0-based index):

 The root node is at index 0.


 If a node is at index i, then:
o Left child is at 2*i + 1
o Right child is at 2*i + 2

Array Representation:
Index 0123456

Node abc de- f

So, the array representation:

[a, b, c, d, e, -, f]

- represents an empty position in the array.

2. Linked List Representation (Binary Tree Using Pointers)

Each node in a linked list representation consists of:

1. Data (value of the node)


2. Pointer to the left child
3. Pointer to the right child

C Structure for Binary Tree Node:

#include <stdio.h>

#include <stdlib.h>
// Define a node structure

struct Node {

char data;

struct Node* left;

struct Node* right;

};

// Function to create a new node

struct Node* createNode(char data) {

struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));

newNode->data = data;

newNode->left = newNode->right = NULL;

return newNode;

// Main function

int main() {

// Creating nodes

struct Node* root = createNode('a');

root->left = createNode('b');

root->right = createNode('c');

root->left->left = createNode('d');

root->left->right = createNode('e');

root->right->right = createNode('f');
printf("Binary tree created using linked list!\n");

return 0;

Explanation of Linked List Structure:

 Each node has three parts:


o Data (stores the character)
o Left pointer (points to left child)
o Right pointer (points to right child)
 The tree is dynamically allocated using malloc().

Q.12What is abstract data type (ADT)? Explain ,why queue is called ADT?

ANs:- Abstract Data Type (ADT)


An Abstract Data Type (ADT) is a mathematical model for a data structure that specifies:

1. What operations can be performed on the data.


2. How the data should behave, without specifying the exact implementation.

ADTs focus on the functionality rather than the implementation details. They define:

 The data it holds.


 The operations allowed (like insertion, deletion, etc.).
 The rules/restrictions on those operations.

Why is Queue Called an ADT?


A Queue is called an Abstract Data Type (ADT) because:

1. It defines a specific behavior:


o FIFO (First-In, First-Out) ordering of elements.
2. It allows basic operations:
o Enqueue (Insertion) → Adds an element to the rear.
o Dequeue (Removal) → Removes an element from the front.
o Peek/Front → Returns the front element without removing it.
o isEmpty() → Checks if the queue is empty.
o isFull() (if using a fixed-size array implementation).
3. The queue does not specify the internal implementation. It can be implemented using:
o Arrays
o Linked Lists
o Stacks
o Circular Buffers

Thus, Queue is an ADT because it provides an interface for operations but does not enforce
a specific way of storing data.

Example Queue Implementations

1. Queue using an Array

#define SIZE 5
int queue[SIZE], front = -1, rear = -1;

void enqueue(int item) {


if (rear == SIZE - 1) {
printf("Queue Overflow\n");
} else {
if (front == -1) front = 0;
queue[++rear] = item;
}
}

int dequeue() {
if (front == -1 || front > rear) {
printf("Queue Underflow\n");
return -1;
}
return queue[front++];
}
2. Queue using a Linked List
struct Node {
int data;
struct Node* next;
};
struct Node* front = NULL, *rear = NULL;

void enqueue(int item) {


struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
newNode->data = item;
newNode->next = NULL;
if (rear == NULL) {
front = rear = newNode;
} else {
rear->next = newNode;
rear = newNode;
}
}
int dequeue() {
if (front == NULL) {
printf("Queue Underflow\n");
return -1;
}
int item = front->data;
struct Node* temp = front;
front = front->next;
free(temp);
return item;
}

Key Takeaways

 Queue is an ADT because it defines what operations can be performed, not how.
 It follows the FIFO principle.
 It can be implemented in multiple ways while still adhering to the defined operations.

Q.13 Explain the following graph terminologies with figures:


i) Undirected Graph
ii) Total Degree of a Vertex
iii) Simple Path
iv) Cycle

Ans:- 1. Undirected Graph

An undirected graph is a graph where edges have no direction. That is, if there is an edge
between two vertices A and B, you can move both ways (A → B and B → A).

✅ Example Figure:

A----B

| |

C----D

 The edges (A, B), (A, C), (B, D), and (C, D) do not have directions.

2. Total Degree of a Vertex

The degree of a vertex is the number of edges connected to it.

 If a vertex has self-loops, they are counted twice.


 Total Degree = Sum of degrees of all vertices.

✅ Example Figure: A----B----C


 Degree of A = 1
 Degree of B = 2
 Degree of C = 1
 Total Degree = 1 + 2 + 1 = 4

3. Simple Path

A simple path is a path between two vertices where:

1. No vertex is repeated.
2. No edge is traversed more than once.

✅ Example Figure:

A→B→C→D

 A simple path from A to D: A → B → C → D.


 If A is visited again, it is not a simple path.

4. Cycle

A cycle is a path where:

1. It starts and ends at the same vertex.


2. No edge is repeated.

✅ Example Figure:

A----B

| |

D----C

 Cycle: A → B → C → D → A

Summary Table

Term Definition Example


Undirected Graph Edges have no direction A—B—C
Total Degree of a Vertex Sum of edges at a vertex Degree (A) = 2
Simple Path Path without repetition A→B→C
Cycle Path starts & ends at same vertex A→B→C→A

You might also like