0% found this document useful (0 votes)
10 views19 pages

DSA Answers

The document provides an overview of various data structures, including primitive and non-primitive types, as well as algorithms for pattern matching, dynamic memory allocation, and tree structures. It includes C code implementations for stack operations, string manipulation, and queue operations, along with explanations of binary trees, threaded binary trees, selection trees, and binary search trees. Additionally, it discusses concepts like chained hashing, dynamic hashing, and traversal algorithms for graphs.

Uploaded by

karthik648464
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
10 views19 pages

DSA Answers

The document provides an overview of various data structures, including primitive and non-primitive types, as well as algorithms for pattern matching, dynamic memory allocation, and tree structures. It includes C code implementations for stack operations, string manipulation, and queue operations, along with explanations of binary trees, threaded binary trees, selection trees, and binary search trees. Additionally, it discusses concepts like chained hashing, dynamic hashing, and traversal algorithms for graphs.

Uploaded by

karthik648464
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 19

01.

Data Structures Overview


Definition​
A data structure is a method of storing data in an organized way in the computer's memory So that data is available
easily.

●​ Storing data in memory


●​ Organizing data in memory
●​ Fetching and processing data

Types of Data Structures

1. Primitive Data Structures

●​ Operated directly by machine-level instructions.


●​ Examples:
○​ int
○​ float
○​ char
○​ double

2. Non-Primitive Data Structures

➢​ Cannot be Operated directly by machine instructions.


➢​ Examples: Arrays, Stacks, Queues, Linked Lists, Trees, Graphs, Files.
➢​ Categories:
○​ Linear Data Structures:​

■​ Data arranged sequentially.


■​ Examples:
●​ Array: A sequence of data items of the same data type.
●​ Stack: Insertions and deletions occur only at one end (Top).
●​ Queue:
○​ Insertions occur at the rear end.
○​ Deletions occur at the front end.
●​ Linked List: A collection of nodes where each node contains data and a link to the
next node.
○​ Non-Linear Data Structures:​

■​ Data items are not arranged sequentially.


■​ Examples:
●​ Atree is a structure of nodes with one root, connected branches, and no cycles.
●​ Graph: A combination of:
○​ Vertices (V)
○​ Edges (E)
○​ Represented as G=(V,E)

1
02.Pattern Matching
Pattern matching is the process of finding all occurrences
of a smaller sequence (pattern) within a larger sequence (text).

Knuth-Morris-Pratt (KMP) Algorithm


The KMP algorithm efficiently searches for a pattern in a text by using
A failure function to avoid unnecessary comparisons.

Steps of KMP Algorithm


●​ String: ABC ABCDAB ABCDABCDABDE
●​ Pattern: ABCDABD

03.C to implement push, pop and display operations for stacks using arrays.

#include<stdio.h>
int stk[10], ch, n, top = -1, item, i;
void push() {
if (top >= n - 1) {
printf("STACK is overflow\n");
} else {
printf("Enter a value to be pushed: ");
scanf("%d", &item);
top++;
stk[top] = item;
printf("Pushed successfully\n");
}
}
void pop() {
if (top == -1) {
printf("Stack is underflow\n");
} else {
printf("The popped element is %d\n", stk[top]);
top--;
}
}
void display() {
if (top == -1) {
printf("STACK is empty\n");
} else {
printf("The elements in STACK are:\n");
for (i = top; i >= 0; i--)
printf("%d\n", stk[i]);
}
}
void main() {
printf("Enter the size of STACK: ");
scanf("%d", &n);
for (;;) {
printf("1.PUSH 2.POP 3.DISPLAY\n");
printf("Enter your choice: ");
scanf("%d", &ch);
switch (ch) {

2
case 1:
push();
break;
case 2:
pop();
break;
case 3:
display();
break;
default:
printf("Invalid choice! Please enter again.\n");
break;
}
}
}

04.Dynamic Memory Allocation


Dynamic memory allocation is the process of allocating memory during program execution (runtime) to allow flexible
use of memory.

Key Functions

1.​ malloc() (Memory Allocation)​

○​ Allocates memory for a specified number of bytes.


○​ Returns a pointer to the first byte of the allocated memory.
○​ Syntax:​
ptr = (datatype *)malloc(size_in_bytes);
○​ Example:​
int *p;
○​ p = (int *)malloc(100 * sizeof(int)); // Allocates memory for 100 integers
2.​ calloc() (Contiguous Allocation)
○​ Allocates memory for multiple blocks of a specified size and initializes all bytes to zero.
○​ Syntax:​
ptr = (datatype *)calloc(number_of_blocks, size_of_each_block);
○​ Example:​
int *p;
○​ p = (int *)calloc(100, sizeof(int)); // Allocates and initializes 100 integers
3.​ realloc() (Resize Memory)
○​ Changes the size of an already allocated memory block.
○​ If needed, it may allocate a new memory block.
○​ Syntax:​
ptr = (datatype *)realloc(ptr, new_size_in_bytes);
○​ Example:​
int *p;
○​ p = (int *)calloc(100, sizeof(int)); // Initial allocation
○​ p = (int *)realloc(p, 200 * sizeof(int)); // Resize to hold 200 integers
4.​ free() (Deallocate Memory)
○​ Releases the memory allocated using malloc(), calloc(), or realloc().
○​ Syntax:​
free(ptr);
○​ Example:​
free(p); // Frees allocated memory

3
05.Write functions in C for the following operations without using built-in
functions i)Compare two strings. ii) Concatenate two strings. iii) Reverse a string

// Function to compare two strings


int scomp(char s1[], char s2[]) {
int i;
// Check if lengths of strings are different
if (strlen(s1) != strlen(s2)) {
return 0; // Return 0 if lengths don't match
}
// Compare character by character
for (i = 0; s1[i] != '\0'; i++) {
if (s1[i] != s2[i]) {
return 0; // Return 0 if any character differs
}
}
return 1; // Return 1 if strings are equal
}
// Function to concatenate two strings
int scat(char s1[], char s2[]) {
int i, j;
// Append characters from s2 to the end of s1
for (i = strlen(s1), j = 0; s2[j] != '\0'; i++, j++) {
s1[i] = s2[j];
}
// Add null terminator at the end of s1
s1[i] = '\0';
return 0; // Indicate success
}
// Function to reverse a string
void reverse(char str[]){
char temp;
int i, j;
i = 0;
j = strlen(str) - 1;
// Swap characters from both ends of the string
while (i < j) {
temp = str[i];
str[i] = str[j];
str[j] = temp;
i++;
j--;
}
// Print the reversed string
printf("\nReversed String Is: %s\n\n", str);
}
// Main function to demonstrate the utility functions
int main() {
// Test cases and demonstration of functions
char s1[100] = "Hello";
char s2[100] = "World";
return 0;
}

06.Define Binary tree. Explain the representation of a binary tree with a suitable
example.

4
Binary Tree
A binary tree is a structure of nodes where:
●​ It is either empty, or
●​ It has a root node and two disjoint subtrees: the left subtree and the right subtree.

Representation of a Binary Tree


1. Array Representation
●​ A binary tree can be stored in a 1D array (sequential representation).
●​ The nodes in a binary tree are numbered starting from 0. Each node's position matches its index in the array
where the tree is stored.

Mapping Rules:
●​ Root node: Stored at a[0]a[0].
●​ Left child of node at index ii: Stored at 2i+12i + 1.
●​ Right child of node at index ii: Stored at 2i+22i + 2.

2. Linked Representation
●​ Each node in the tree is represented as an object with three fields:
1.​ LeftChild: Points to the left subtree.
2.​ RightChild: Points to the right subtree.
3.​ Data: Stores the actual value of the node.

07. Define the Threaded binary tree. Construct Threaded binary for the following elements:
A, B, C, D, E, F, G, H, I

A threaded binary tree is a special kind of binary tree where:


●​ Each node has an extra pointer called a thread.
●​ The thread points to the next or previous node in the in-order sequence.
This makes it easy to go through the tree without needing extra memory.

5
8. Define selection tree. Construct min winner tree for the runs of a game given below.
Each run consists of the values of players. Find the first 5 winners

Selection Tree (Tournament Tree)

●​ A selection tree helps find the smallest (or largest) value in a group efficiently.
●​ It’s a complete binary tree used in tournaments.
●​ it is also called as tournament tree

Types:

1.​ Winner Tree: Each node stores the smaller value of its two children, and the root holds the smallest value.
2.​ Loser Tree: Tracks the second smallest/largest values.

6
9.Define Binary Search tree. Construct a binary search tree (BST) for the following
elements: 100, 85, 45, 55, 120, 20, 70, 90, 115, 65, 130, 145. Traverse using in-order,
pre-order, and post-order traversal techniques. Write recursive C functions for the same.

A binary search tree (BST) is a special type of tree where:

1.​ Each element has a unique key.


2.​ In a subtree:
○​ All keys in the left subtree are smaller than the key of the root.
○​ All keys in the right subtree are larger than the key of the root.
3.​ Both the left and right subtrees are themselves binary search trees.

7
10.Construct a binary tree from the Post-order and In-order sequence given below
In-order: GDHBAEICF
Post-order: GHDBIEFCA


11.Define Forest. Transform the given forest into a Binary tree and traverse using inorder,
preorder and postorder traversal.

Definition of a Forest
A forest is a collection of one or more disjoint trees.

8
12.What is chained hashing? Discuss its pros and cons. Construct the hash table to insert the
keys: 7, 24, 18, 52, 36, 54, 11, 23 in a chained hash table of 9 memory locations. Use h(k) = k mod.
Chained Hashing

●​ Chained hashing is a method to handle collisions in hash tables.


●​ When multiple elements map to the same index, they are stored in a linked list at that index..

Advantages

●​ Easy to implement.
●​ Efficient for insertion and deletion.
●​ Handles dynamic data sizes.
●​ Works with diverse data distributions.

Disadvantages

●​ Requires extra memory for linked lists.


●​ Cache inefficient for large tables.
●​ Performance degrades with long linked lists.
●​ Worst-case lookups can be slow.

13.Design an algorithm to traverse a graph using Depth First Search (DFS). Apply DFS for
the graph given below.

Here’s a simplified version of the steps:

1.​ Step 1: Go to an unvisited adjacent vertex, mark it as visited, display it, and push it onto
the stack.
2.​ Step 2: If no unvisited adjacent vertex exists, pop the top vertex from the stack.
3.​ Step3: Continue steps 1 and 2 until the stack is empty.

9
14.Dynamic Hashing

Dynamic hashing is a technique that allows the hash table to expand or shrink as needed when new records are added or existing
records are removed. This flexibility prevents performance issues that arise when a fixed-size hash table becomes too full or too
sparse.

Dynamic Hashing with Directories (Extendible Hashing)

Key Concepts:

●​ Buckets: Containers that hold the actual data (records).


●​ Directories: They hold pointers to buckets and have unique identifiers (IDs) to help locate buckets.
●​ Global Depth: Represents the number of bits used by the hash function to divide the data.

Directory-Less Dynamic Hashing (Simplified)

●​ In directory-less dynamic hashing, there is no directory to manage pointers to data buckets.


●​ Instead, all data (records) is stored in a single, continuous memory block.

How It Works:

1.​ A hash function is used to directly calculate the exact location (address) of the data in memory.
2.​ This eliminates the need for an extra directory to point to buckets.

Key Points:

●​ Data is directly stored and retrieved using the hash function.


●​ The hash function acts like a "shortcut" to find the correct bucket in memory.
●​ There’s no need to manage or expand directories, making the process simpler.

It’s like using a precise address to reach a house directly, instead of first looking it up in a directory.

15.Write recursive C functions for inorder, preorder and postorder traversals of a binary
tree. Also, find all the traversals for the given tree.

C FUNCTIONS FOR THIS IS SAME AS QUESTION NUMBER 9

10
16.a Develop a C program to implement insertion, deletion and display operations on
Linear queue.
#include <stdio.h>
int q[10], ch, size, front = -1, rear = -1, item, i;
void enqueue() {
if (rear == size - 1) {
printf("Queue Overflow\n");
} else {
if (front == -1) {
front = 0;
}
printf("Insert the element in queue: ");
scanf("%d", &item);
q[++rear] = item; // Fixed rear increment before assignment
}
}
void dequeue() {
if (front == -1 || front > rear) {
printf("Queue Underflow\n");
} else {
printf("Element deleted from queue is: %d\n", q[front]);
front++;
}
}
void display() {
if (front == -1 || front > rear) {
printf("Queue is empty\n");
} else {
printf("Queue is:\n");
for (i = front; i <= rear; i++) {
printf("%d\n", q[i]);
}
}
}
int main() {
printf("Enter the size of the queue: ");
scanf("%d", &size);

while (1) {
printf("1. Insert 2. Delete 3. Display\n");
printf("Enter your choice: ");
scanf("%d", &ch);

switch (ch) {
case 1:
enqueue();
break;
case 2:
dequeue();
break;
case 3:
display();
break;
default:
printf("Invalid choice! Try again.\n");
}
}
return 0;
}

11
17.Write a C program to implement insertion, deletion and display operations on a
circular queue.

#include <stdio.h>
#define SIZE 10
int cq[SIZE], front = -1, rear = -1, item, ch, i;
void enQueue()
{
if (front == (rear + 1) % SIZE)
{
printf("CIRCULAR QUEUE IS OVERFLOW\n");
}
else
{
printf("Enter element:\n");
scanf("%d", &item);
rear = (rear + 1) % SIZE;
cq[rear] = item;
printf("Inserted\n");
}
}
void deQueue()
{
if (front == -1)
{
printf("CIRCULAR QUEUE IS UNDERFLOW\n");
}
else
{
printf("\nDeleted element -> %d\n", cq[front]);
if (front == rear)
front = rear = -1; // Reset the queue
else
front = (front + 1) % SIZE;
}
}
void display()
{
if (front == -1)
{
printf("CIRCULAR QUEUE IS EMPTY\n");
}
else
{
printf("Items are:\n");
for (i = front; i != rear; i = (i + 1) % SIZE)
{
printf("%d\n", cq[i]);
}
printf("%d\n", cq[i]); // Print the last element
}
}
void main()
{
while (1)
{
printf("1. Insert 2. Delete 3. Display 4. Exit\n");
printf("Enter your choice:\n");
scanf("%d", &ch);
switch (ch)

12
{
case 1: enQueue(); break;
case 2: deQueue(); break;
case 3: display(); break;
case 4: return; // Exit the program
default: printf("Invalid choice, try again!\n");
}
}
}

18.Write a function to evaluate the postfix expression. Illustrate the same for the given
postfix expression: ABC-D*+E$F+ and assume A=6, B=3, C=2, D=5, E=1 and F=7.

#include <stdio.h>
#include <string.h>
#include <math.h>
#include <ctype.h>
float compute(char symbol, float op1, float op2) { POSTFIX EXPRESSION
switch (symbol) {
case '+': return op1 + op2;
case '-': return op1 - op2;
case '*': return op1 * op2;
case '/': return op1 / op2;
case '$': // Fallthrough for '^'
case '^': return pow(op1, op2);
default:
printf("Invalid operator: %c\n", symbol);
return 0;
}
}
void main() {
float s[20], res, op1, op2;
int top, i;
char postfix[20], symbol;
printf("\nEnter the postfix expression:\n");
scanf("%s", postfix);
top = -1;
for (i = 0; i < strlen(postfix); i++) {
symbol = postfix[i];
if (isdigit(symbol)) {
s[++top] = symbol - '0'; // Convert character digit to integer
} else {
op2 = s[top--];
op1 = s[top--];
res = compute(symbol, op1, op2);
s[++top] = res;
}
}
res = s[top--];
printf("\nThe result is : %f\n", res);
}

13
19. Write the C function to add two polynomials. Show the linked representation of the
below two polynomials and their addition using a circular singly linked list
P1: 5x3 + 4x2 +7x + 3
P2: 6x2 + 5 Output:
add the above two polynomials and represent them using the linked list
poly_pointer padd(poly_pointer a, poly_pointer b) {
poly_pointer c, rear, temp;
int sum;
// Initialize rear and front pointers
rear = (poly_pointer)malloc(sizeof(poly_node));
c = rear;
// Traverse through both polynomial lists
while (a && b) {
switch (COMPARE(a->expon, b->expon)) {
case -1:
/* a->expon < b->expon */
attach(b->coef, b->expon, &rear);
b = b->link;
break;
case 0:
/* a->expon == b->expon */
sum = a->coef + b->coef;
if (sum)
attach(sum, a->expon, &rear);
a = a->link;
b = b->link;
break;
case 1:
/* a->expon > b->expon */
attach(a->coef, a->expon, &rear);
a = a->link;
break;
}
}
// Attach the remaining terms from either polynomial
while (a) {
attach(a->coef, a->expon, &rear);
a = a->link;
}
while (b) {
attach(b->coef, b->expon, &rear);
b = b->link;
}

// Terminate the result list


rear->link = NULL;
return c->link;
}

20.Write C functions for the following

A)Search an element in the singly linked list.


B)Concatenation of two singly linked list

14
20 Define Sparse matrix. For the given sparse matrix, give the linked list representation:

●​ Sparse matrix is a special matrix made of m rows and n columns.


●​ Most of its elements in the sparse matrix are zero.
●​ We can also assume that if (m * n) / 2 elements are zero then it is a sparse matrix.

Linked LIst Representation

21..Define the Disjoint set. Consider the tree created by the weighted union function on
the sequence of unions: union(0,1), union(2,3), union(4,5), union(6,7), union(0,2),
union(4,6), and union(0,4). Process the simple find and collapsing find on eight finds and
compare which find is efficient.

15
Disjoint:Disjoint set is a set of which element are not repeated inside the disjoint set
should be unique and should not be repeated

16
22. What is a Priority queue? Demonstrate functions in C to implement the Max Priority
queue with an example. i) Insert into the Max priority queue ii) Delete into the Max priority
queue iii) Display Max priority queue
●​ It is a collection of ordered elements that provides fast access to the minimum or maximum element.

// Function to insert an element into the Max Priority Queue


void insert(MaxPriorityQueue *pq, int value) {
if (pq->size == MAX) {
printf("Priority Queue is full!\n");
return;
}
pq->data[pq->size] = value;
int i = pq->size;
pq->size++;

// Heapify upwards to maintain max heap property


while (i > 0 && pq->data[(i - 1) / 2] < pq->data[i]) {
int temp = pq->data[i];
pq->data[i] = pq->data[(i - 1) / 2];
pq->data[(i - 1) / 2] = temp;
i = (i - 1) / 2;
}
printf("Inserted %d into the Max Priority Queue\n", value);
}
// Function to delete the maximum element from the Max Priority Queue
void deleteMax(MaxPriorityQueue *pq) {
if (pq->size == 0) {
printf("Priority Queue is empty!\n");
return;
}
printf("Deleted %d from the Max Priority Queue\n", pq->data[0]);
pq->data[0] = pq->data[pq->size - 1];
pq->size--;

// Heapify downwards to maintain max heap property


int i = 0;
while ((2 * i + 1) < pq->size) {
int largest = i;
int leftChild = 2 * i + 1;
int rightChild = 2 * i + 2;
if (leftChild < pq->size && pq->data[leftChild] > pq->data[largest]) {
largest = leftChild;
}
if (rightChild < pq->size && pq->data[rightChild] > pq->data[largest]) {
largest = rightChild;
}
if (largest == i) break;
int temp = pq->data[i];
pq->data[i] = pq->data[largest];
pq->data[largest] = temp;
i = largest;
}
}
// Function to display the Max Priority Queue
void display(MaxPriorityQueue *pq) {
if (pq->size == 0) {
printf("Priority Queue is empty!\n");
return;
}
printf("Max Priority Queue: ");
for (int i = 0; i < pq->size; i++) {
printf("%d ", pq->data[i]);
}
printf("\n");
}

17
23.Define hashing. Explain different hashing functions with examples. Discuss the
properties of a good hash function.
Definition: Hashing is a process of mapping large data (keys) to smaller, fixed-size values (hash codes) using a
mathematical function (hash function).

Types of Hash Functions and Examples

1. Division Hash Function

●​ Method: Use the modulus operator to divide the key by the table size mm.
●​ Formula: H(x)=KEY%mH(x) = \text{KEY} \% m.
●​ Example:
○​ Key: x=23x = 23, Table size: m=10m = 10.
○​ H(x)=23%10=3H(x) = 23 \% 10 = 3.
○​ The key 2323 is placed at the 3rd location.

2. Mid Square Hash Function

●​ Method: Square the key, extract digits from the middle, and use them as the address.
●​ Example:
○​ Key: 1616.
○​ Square: 162=25616^2 = 256.
○​ Extract middle digits: 5656 (if 2-digit address is required).
○​ Address: 5656.

3. Folding Hash Function

●​ Method: Partition the key into equal parts and process them.​

(a) Fold-Shifting:​

○​ Add all parts directly.


○​ Example:
■​ Key: 1234567812345678.
■​ Break into parts: 12,34,56,7812, 34, 56, 78.
■​ Add parts: 12+34+56+78=18012 + 34 + 56 + 78 = 180.
■​ Ignore the first digit to get a 2-digit address: 8080.
●​ (b) Fold-Boundary:​

○​ Reverse outer parts of the key before adding.


○​ Example:
■​ Key: 1234567812345678.
■​ Break into parts: 12,34,56,7812, 34, 56, 78.
■​ Reverse outer parts: 21,34,56,8721, 34, 56, 87.
■​ Add parts: 21+34+56+87=19821 + 34 + 56 + 87 = 198.
■​ Ignore the first digit to get a 2-digit address: 9898.

4. Digit Analysis

●​ Method: Analyze the key's digits statistically and use frequently occurring digits to form the address.
●​ Example:
○​ Key: 98612349861234.
○​ Select positions: 3rd3^{rd} and 5th5^{th} digits (6,26, 2).
○​ Combine digits: 6262.
○​ Reverse the digits: 2626 (final address).

18
19

You might also like