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

Jeshwanth Ds

Dst

Uploaded by

tjeshwanthgoud
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)
15 views19 pages

Jeshwanth Ds

Dst

Uploaded by

tjeshwanthgoud
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

1. Write the algorithm for bubble sort and explain with an example.

The algorithm known as Bubble Sort


Iteratively going over the list, bubble sort is a simple sorting
technique that compares nearby components and swaps them if
they are out of order. This step is repeated until the list is sorted. As
the name suggests, the larger elements "bubble" to the top of the
list.
Algorithm: Start:
Enter the size of the array (𝑛).
The external loop
Repeat 𝑛 n−1 times (for every pass). Internal Loop:
The following applies to each element i from index 0 to n−k−1 (where
k is the pass number):
Take a look at the subsequent element.
If the current element is larger than the next, switch them.
Pseudocode:
text
Copy code
bubbleSort(arr, n):
for i = 0 to n - 1:
swapped = false
for j = 0 to n - i - 2:
if arr[j] > arr[j + 1]:
swap(arr[j], arr[j + 1])
swapped = true
if not swapped:
break
2. Explain the Binary Search procedure for the following list of
elements and assume the key element is 85. 12, 23, 34, 45, 55, 62,
71, 85, 96
Methodology for Binary Search
Binary search is a useful technique for finding a target element in a
sorted array. It continuously cuts the search period in half while
comparing the middle element with the target key.
Initial Conditions: [12, 23, 34, 45, 55, 62, 71, 85, 96] is the array.
45, 55, 62, 71, 85, 96, 12, 23, 34, and 45
Key to search: 85 85
Boundaries first:
Low (first index) = 0. High = 8 (last index) Low = 0 Elevated = 8.
Algorithm Steps: Step 1: Determine the Middle Inde
Mid = ⌊( Low + High) / 2 ⌋ = ⌊( 0 + 8) / 2 ⌋ = 4
(Low+High)/2⌋=(0+8)/2⌋=4 = Mid
The middle element
Array[Mid] = 55
Array[Mid]=55
In contrast:

The key must be in the right half because 55<85.


Change the borders to Low = 5 Low = 5 High = 8 High = 8.
Step 2: Determine the Middle Index again
Mid = ⌊( Low + High) / 2 ⌋ = ⌊( 5 + 8) / 2 ⌋ = 6
(Low+High)/2⌋=(5+8)/2⌋=6 = Mid
The middle element
Array[Mid] = 71
Array[Mid]=71
In contrast:

71 to 85
71<85, hence the right half must hold the key.
Refresh the boundaries: Low = 7.
Low = 7, High = 8.
High is 8.
Recalculate the Middle Index in Step Three.

Mid = ⌊( Low + High) / 2 ⌋ = ⌊( 7 + 8) / 2 ⌋ = 7


(Low+High)/2⌋=(7+8)/2⌋=7 Mid=
The middle element
Array[Mid] = 85
Array[Mid]=85
In contrast:

Since 85 = 85 = 85, index 7 contains the key.


As a result, key 85 is found in the array at index 7.
3. Describe the operations of a stack using stacks using arrays.
In order to teach stack operations using a stack constructed with
arrays, we will disassemble the basic stack operations of push, pop,
peek, and isEmpty.

Implementing Stack Operations with Arrays


When implementing a stack with an array:

Array: A fixed-size array contains the elements.


Top: A variable keeps track of the index of the element at the top of
the stack.
Capacity: The array size determines the stack's maximum capacity.
1. The Push Function
Definition: Adds an element to the stack's top. The operation fails
with a stack overflow error if the stack is full.

Actions to take:
Verify whether the stack is full:
In the event that top = capacity −1, print "Stack Overflow."
If not, increase top top.
The new element should go at array[top]array[top].
The algorithm

text
Code push(stack, element) is copied:
Should top equal capacity minus one, print "Stack Overflow"
stack[top] = element; return top = top + 1
4. Evaluate the following postfix notation of expression (Show
status of stack after execution of each operations): 520 15-252*+
Stack
Step Token Action Explanation
(Status)
1 520 Push 520 onto the stack. [520] Operand, push onto stack.
[520,
2 15 Push 15 onto the stack. Operand, push onto stack.
15]

-
Pop 15 and 520, compute [505]
520−15=505520 - 15 =
3
520−15520 - 15520−15. 505520−15=505, push the result.
[505,
4 252 Push 252 onto the stack. Operand, push onto stack.
252]
Pop 252 and 505, compute 505×252=127260505 \times 252 =
5 * 505×252505 \times [127260] 127260505×252=127260, push the
252505×252. result.
Pop 127260, compute 127260+0=127260127260 + 0 =
6 + 127260+0127260 + [127260] 127260127260+0=127260, push the
0127260+0. result.

5. Write a program to split a circular linked list into two halves.


class Node {
int data;
Node next;
public Node(int data) {
this.data = data;
this.next = null;
}
}
class CircularLinkedList {
Node head;
// Add a node to the circular linked list
public void append(int data) {
Node newNode = new Node(data);
if (head == null) {
head = newNode;
newNode.next = head; // Point back to itself
} else {
Node temp = head;
while (temp.next != head) {
temp = temp.next;
}
temp.next = newNode;
newNode.next = head; // Maintain circularity
}
}
// Display the circular linked list
public void display(Node head) {
if (head == null) {
System.out.println("List is empty.");
return;
}
Node temp = head;
do {
System.out.print(temp.data + " -> ");
temp = temp.next;
} while (temp != head);
System.out.println("(back to start)");
}
// Split the circular linked list into two halves
public Node[] splitIntoTwoHalves() {
if (head == null || head.next == head) {
return new Node[]{head, null}; // If the list is empty or has one
element
}
// Step 1: Find the middle of the circular linked list
Node slow = head, fast = head;
while (fast.next != head && fast.next.next != head) {
slow = slow.next;
fast = fast.next.next;
}

// Step 2: Split into two halves


Node head1 = head; // First half starts from the head
Node head2 = slow.next; // Second half starts after the middle
node
slow.next = head1; // End the first half
if (fast.next == head) {
fast.next = head2; // End the second half
} else {
fast.next.next = head2;
}
return new Node[]{head1, head2};
}
public static void main(String[] args) {
CircularLinkedList cll = new CircularLinkedList();
// Append data to the circular linked list
cll.append(1);
cll.append(2);
cll.append(3);
cll.append(4);
cll.append(5);
System.out.println("Original Circular Linked List:");
cll.display(cll.head);
// Split the list into two halves
Node[] halves = cll.splitIntoTwoHalves();
System.out.println("\nFirst Half:");
cll.display(halves[0]);
System.out.println("\nSecond Half:");
cll.display(halves[1]);
}
}
6. Write a program to create a doubly linked list and print nodes
from the current position to the first node.
class Node {
int data;
Node next;
Node prev;
public Node(int data) {
this.data = data;
this.next = null;
this.prev = null;
}
}
class DoublyLinkedList {
private Node head;
// Add a node to the end of the doubly linked list
public void append(int data) {
Node newNode = new Node(data);
if (head == null) {
head = newNode;
} else {
Node temp = head;
while (temp.next != null) {
temp = temp.next;
}
temp.next = newNode;
newNode.prev = temp;
}
}

// Print nodes from the current position to the first node


public void printReverseFrom(Node current) {
if (current == null) {
System.out.println("Current node is null. Cannot print.");
return;
}

System.out.println("Printing from current position to the first


node:");
Node temp = current;
while (temp != null) {
System.out.print(temp.data + " ");
temp = temp.prev;
}
System.out.println();
}

// Get a node at a specific position (1-based index)


public Node getNodeAtPosition(int position) {
if (position <= 0) {
System.out.println("Invalid position.");
return null;
}
Node temp = head;
int index = 1;
while (temp != null && index < position) {
temp = temp.next;
index++;
}
if (temp == null) {
System.out.println("Position exceeds list length.");
}
return temp;
}

// Print the entire list (for reference)


public void printList() {
if (head == null) {
System.out.println("List is empty.");
return;
}
Node temp = head;
while (temp != null) {
System.out.print(temp.data + " ");
temp = temp.next;
}
System.out.println();
}
}

public class Main {


public static void main(String[] args) {
DoublyLinkedList dll = new DoublyLinkedList();

// Add elements to the doubly linked list


dll.append(10);
dll.append(20);
dll.append(30);
dll.append(40);
dll.append(50);

System.out.println("Doubly Linked List:");


dll.printList();

// Get a node at position 3 and print in reverse from there


Node current = dll.getNodeAtPosition(3); // Node with value 30
dll.printReverseFrom(current);
}
}
7. Define a full binary tree and complete binary tree?
Complete Binary Tree: A complete binary tree is one in which each
node has two or zero offspring. This implies:

There can be more than one kid per node in the tree.
With the possible exception of the leaf level, the tree's structure is
perfectly balanced.
Full Binary Tree: An entire binary tree is one in which:

Every level is fully occupied, with the possible exception of the final
one.
The last level's nodes are oriented as far to the left as feasible.
Important Distinctions:

Nodes in the last level of a full binary tree can be empty or have just
one child as long as they are filled from left to right.
Unlike a complete binary tree, it does not require every node to have
two offspring.
Key Comparison:
Property Full Binary Tree Complete Binary Tree
Each node has 0 or 2 Nodes may have 0, 1, or
Node Children
children. 2 children.
Property Full Binary Tree Complete Binary Tree
No specific alignment
Last Level Nodes are left-aligned.
rule.

Structure Strictly balanced except Balanced except for the


Requirement for leaves. last level.

8. Let G be a graph with n vertices and m edges. Find the tightest


upper bound on the running time on depth first search of graph G.
Assume that graph is represented using adjacency matrix.
To achieve the tightest upper bound on the running time of DFS on a
graph G with n vertices and m edges, we assume that the graph is
represented by an adjacency matrix. To do this, we need to consider
how DFS works and how the adjacency matrix affects the time
complexity.

An outline of the DFS Algorithm for Step-by-Step Analysis:

Starting from a selected vertex, DFS moves as far as it can along each
branch before turning around.
DFS uses a recursive or stack-based approach to graph exploration.
Each vertex may only be visited once, and each edge may only be
examined once.
Complexity of DFS Time:

Every vertex and edge in the entire graph will be investigated by the
DFS algorithm.

DFS determines whether an edge exists for each vertex by looking at


all other vertices. The adjacency matrix is used for this.

Time spent on each vertex: Every vertex is processed individually,


and processing a vertex takes time because it includes examining
each of the n vertices to determine whether the current vertex has
an edge. Each vertex undergoes this check, which uses the adjacency
matrix and takes 𝑂 (1 O(1) time).

9. Construct a M-way search tree of order 3 for the following nodes


20,70,110,210,130
Building an Order 3 M-way Search Tree
A node can have three children and store up to two keys in each
node of an M-way search tree of order three, sometimes referred to
as a 3-way search tree or ternary search tree. For the keys 20, 70,
110, 210, and 130, we will build a three-way search tree with order
3.

The following are the primary guidelines for adding to a three-way


search tree:

Since it's of order 3, each node may only contain a maximum of two
keys (M−1=3−1=2, hence 𝑀−1 = 3−1 = 2).
Step-by-Step Insertion into the M-way Search Tree
1. Insert 20:
o The tree is empty, so 20 becomes the root.
o The tree looks like this:
csharp
Copy code
[20]
2. Insert 70:
o 70 is greater than 20, so it is inserted to the right of 20.
o The tree now contains two keys: 20 and 70.
o The tree looks like this:
csharp
Copy code
[20, 70]
3. Insert 110:
o 110 is greater than 70, so it is inserted to the right of 70.
o Since the node now has 3 keys (more than the allowed 2),
we split the node.
o The middle key (70) is moved up to become the new root,
and the other two keys (20 and 110) are split into two
nodes.
o The tree now looks like this:
csharp
Copy code
[70]
/ \
[20] [110]
1. Insert 210:
o 210 is greater than 110, so it is inserted to the right of
110.
o The tree now looks like this:
csharp
Copy code
[70]
/ \
2. [20] [110, 210]
3. Copy code
4. Insert 130:
o 130 is greater than 110 but less than 210, so it is inserted
between 110 and 210.
o The node [110, 210] will now have 3 keys (110, 130, 210),
which causes a split.
o The middle key (130) moves up to the root, and the node
is split into two nodes: [110] and [210].
o The tree now looks like this:
css
Copy code
[70, 130]
/ | \
[20] [110] [210]

Final M-Way Search Tree of Order 3


After inserting all the keys (20, 70, 110, 210, and 130), the final 3-
way search tree looks like this:
css
Copy code
[70, 130]
/ | \
[20] [110] [210]

10. A cosmetician wants to represent a list of her clients? records


(by their ID). For each client we would like to mark whether he is a
man or she is a woman. Suggest a data structure that supports the
following operations in O(log n) time in the worst case, where n is
the number of persons (men and women) in the data structure
when the operation is executed: 1. Insert(k, c) - Insert a new client c
with id = k to the data structure, at first mark the client as a
woman. 2. Update(k)? Update client with ID = k to be a man. 3.
FindDiff(k)? Find the difference between the number of women and
the number of men (? #of women #of men?) among all the clients
with ID smaller than k
To efficiently represent the list of clients, each with a gender (woman
or man), and support the specified operations in O(log⁡n)O(\log
n)O(logn) time in the worst case, a self-balancing binary search tree
(BST) would be an ideal data structure. Specifically, a Red-Black Tree
or AVL Tree can be used, as both allow for efficient searching,
insertion, and updates in O(log⁡n)O(\log n)O(logn) time in the worst
case.
Let’s break down the operations and explain how we can implement
them using a Red-Black Tree (though the same logic applies to other
self-balancing BSTs like AVL trees):
Data Structure Choice:
 Red-Black Tree: This is a balanced binary search tree where the
nodes are colored (red or black) to maintain balance, ensuring
that the tree height remains O(log⁡n)O(\log n)O(logn) for all
operations (insertions, deletions, and searches).
Node Structure: The Red-Black Tree's nodes will each include:

Client ID (k): The client's special identification number.


Gender (g): A flag that indicates the client's gender. This will be
set to 'lady' at first.
Subtree Size (size): This effectively calculates the difference
between the number of women and men for FindDiff by
monitoring the size of the subtree rooted at the current node.
Activities:
Insert (k, c):
Mark the new client as female (initial gender) and insert them
with ID k.
Follow the Red-Black Tree's regular insertion process.
Every ancestor node in the tree should have its size updated.
O(logn) is the time required for this operation because of the
tree's balancing features.

You might also like