C-3 (Dsa)
C-3 (Dsa)
C-3 (Dsa)
A data structure is a way of organizing and storing data to perform operations efficiently. It defines the
relationships and operations that can be performed on the data, facilitating efficient access, modification,
and retrieval of information. Common examples include arrays, linked lists, stacks, queues, trees, and
graphs.
2. Diff b/w
★Linear:
1. Data elements are arranged in a sequential manner, one after the other.
2. Elements can be accessed in a linear or sequential order.
3. It uses memory efficiently, and elements are stored in a contiguous block of memory.
4. Arrays, Linked Lists, Stacks, and Queues are common linear data structures.
5.Traversing or moving through elements involves visiting them one by one in a specific order.
Non linear:
1. Data elements are not organized sequentially; they have a hierarchical or interconnected
structure.
2. Elements can be accessed in a more random or non-sequential manner.
3. It may use memory less efficiently compared to linear structures as elements are not stored in a
contiguous block.
4. Trees and Graphs are common nonlinear data structures.
5. Traversing elements might involve navigating through different paths and branches, not
necessarily in a linear order.
1. Primitive data structures are basic and fundamental types of data that are directly operated
upon by the computer's hardware.
2. Common examples include integers, floating-point numbers, characters, and booleans.
3. They are used to store simple values and are the building blocks for more complex data
structures.
4. They have fixed sizes and are usually represented directly in machine memory.
1. Non-primitive data structures are more advanced and complex, constructed using primitive
data types as well as other non-primitive data structures.
2. Arrays, linked lists, stacks, queues, trees, and graphs are common non-primitive data structures.
3. They are designed to organize and manage collections of data, offering more flexibility and
functionality than primitive types alone.
4. Their size is dynamic and may vary based on the amount of data they contain.
1. In static data structures, memory allocation is fixed and predetermined during compile-time.
2. The size of the data structure is constant and doesn't change during program execution.
3. Arrays are a common example of a static data structure. Once an array is declared, its size is
fixed, and it cannot be easily changed.
4. Static data structures can be more memory-efficient in terms of storage because the size is
known in advance.
1. In dynamic data structures, memory is allocated during runtime, and the size can be adjusted
as needed.
2. The size of the data structure can change dynamically based on the program's requirements.
3. Linked lists, stacks, queues, trees, and dynamic arrays (like Array List in Java) are examples of
dynamic data structures.
4. Dynamic data structures provide more flexibility as they can grow or shrink based on the data
being processed.
5. While dynamic data structures offer flexibility, they may involve more overhead due to dynamic
memory allocation and deallocation.
★Linear Queue:
1. In a linear queue, elements are arranged in a straight line, and the queue has a front and a rear.
2. It can suffer from overflow (when trying to enqueue in a full queue) and underflow (when
trying to dequeue from an empty queue) conditions.
3. Enqueue (adding an element to the rear) and dequeue (removing an element from the front)
operations follow a linear order.
4. Memory for a linear queue is allocated in a linear or sequential manner.
Circular Queue:
1. In a circular queue, the last element is connected to the first element, forming a circle.
2. Circular queues efficiently handle overflow and underflow conditions. When the rear reaches
the end, it can wrap around to the front.
3. Enqueue and dequeue operations are performed in a circular fashion, and they wrap around
the queue if needed.
4. Memory is allocated in a circular manner, allowing efficient use of space.
# Example usage:
push_to_stock("Apple")
push_to_stock("Banana")
push_to_stock("Orange")
popped_item = pop_from_stock()
output:
4. what is asymptotic natation and how to find the time complexity in best, worth, average case??
Asymptotic notation is a mathematical notation used to describe the limiting behavior of a function as
its input approaches infinity. It is commonly used in the analysis of algorithms to express the upper and
lower bounds on the running time or space complexity.
To find the time complexity in the best, worst, and average cases, We typically follow these steps:
1. Best Case:
• Identify the scenario where your algorithm performs optimally.
• Analyze the number of basic operations or steps required in this best-case scenario.
• Express the best-case time complexity using Omega (Ω) notation.
2. Worst Case:
• Identify the scenario where your algorithm performs the least optimally.
• Analyze the number of basic operations or steps required in this worst-case scenario.
• Express the worst-case time complexity using Big O (O) notation.
3. Average Case:
• Analyze the average number of basic operations or steps required over all possible
inputs.
• Express the average-case time complexity using Theta (Θ) notation.
5. what is deque and explain the type of deque??
A deque, short for double-ended queue, is a data structure that allows insertion and deletion of
elements from both ends – the front and the rear. It combines the features of a stack and a queue,
providing more flexibility in managing data.
There are two main types of deques based on how elements are added and removed:
1. Town of Hanoi
2. infix, postfix conversion using stack
1. Tower of Hanoi:
• Description: The Tower of Hanoi is a classic problem that involves moving a tower of discs
from one rod to another, subject to the constraint that a larger disc cannot be placed on top of
a smaller one.
• Stack Application: The Tower of Hanoi is often solved using a recursive algorithm that mimics
the behavior of a stack. Each recursive call corresponds to moving a sub-tower. The stack
stores the state of each recursive call, helping in the systematic movement of discs.
• Description: Infix notation is the standard mathematical notation where operators are placed
between operands (e.g., 2 + 3). Postfix (or Reverse Polish Notation) is an alternative notation
where operators follow their operands (e.g., 2 3 +).
• Stack Application: Converting infix to postfix involves using a stack to keep track of operators
and ensuring the correct order of operations. The stack helps in managing the precedence of
operators and handling parentheses effectively. The algorithm scans the infix expression, and
the stack ensures the proper ordering of operators during the conversion process.
7. what is linked list. the diff b/w array and linked-list & perform the following algorithms in single
linked-list.
A linked list is a linear data structure consisting of nodes, where each node contains data and a reference (or link)
to the next node in the sequence. It forms a chain-like structure, and the last node typically points to null,
indicating the end of the list. Unlike arrays, linked lists don't require contiguous memory, allowing for dynamic and
efficient memory allocation.
2. **Size:**
- Array: Fixed size.
- Linked List: Dynamic size, can grow or shrink during runtime.
4. **Access Time:**
- Array: Direct access to elements using index.
- Linked List: Sequential access, requires traversal from the beginning.
These algorithms take advantage of the dynamic nature of linked lists, making insertions and deletions efficient
compared to arrays.
9. what is tree? explain BST and Traversal in tree using in order, pre order, post order.
A tree is a hierarchical data structure that consists of nodes connected by edges. It is widely used in computer
science to represent hierarchical relationships or structures. In a tree:
A Binary Search Tree (BST) is a special type of binary tree where each node has at most two children, and the key
(value) of each node is greater than or equal to the keys of all nodes in its left subtree and less than or equal to the
keys of all nodes in its right subtree. This property ensures efficient searching, insertion, and deletion operations.
Traversal in a tree refers to the process of visiting all the nodes in a specific order. There are three common ways to
traverse a binary tree:
These traversal methods are commonly used for various operations on binary trees, such as searching for a
specific node, printing the nodes in a specific order, or evaluating expressions represented by the tree.
```plaintext
4
/\
2 6
/\/\
1 35 7
```
- In-order traversal: 1, 2, 3, 4, 5, 6, 7
- Pre-order traversal: 4, 2, 1, 3, 6, 5, 7
- Post-order traversal: 1, 3, 2, 5, 7, 6, 4
10. construct tree using in order and pre order traversal result.
Constructing a binary tree using the in-order and pre-order traversals involves the following steps:
1. **Given:**
- In-order traversal: [D, B, E, A, F, C]
- Pre-order traversal: [A, B, D, E, C, F]
2. **Identify Root:**
- The first element in the pre-order traversal is the root of the tree.
- Root = A
3. **Split In-order:**
- Find the root in the in-order traversal. Elements to the left are part of the left subtree, and elements to the right
are part of the right subtree.
- In-order left subtree: [D, B, E]
- In-order right subtree: [F, C]
4. **Recursion:**
- Recursively repeat the process for the left and right subtrees using the remaining pre-order elements.
- For the left subtree:
- Pre-order: [B, D, E]
- In-order: [D, B, E]
- Root: B (first element in the new pre-order)
- Left subtree: [D], Right subtree: [E]
- For the right subtree:
- Pre-order: [C, F]
- In-order: [F, C]
- Root: C (first element in the new pre-order)
- Left subtree: [F]
The resulting binary tree for the given in-order and pre-order traversals is:
```plaintext
A
/\
B C
/\ \
D E F
```
11. what is threaded binary tree? explain the advantage with example?
A threaded binary tree is a binary tree with additional links, called threads, that connect some nodes to their in-
order successor or predecessor. These threads help in traversing the tree efficiently without using recursion or a
stack.
1. **Efficient Traversal:**
- Threaded binary trees allow for quick in-order traversals without the need for recursive function calls or an
explicit stack.
- This is particularly beneficial in scenarios where memory usage needs to be minimized.
2. **Space Efficiency:**
- Threads reduce the need for extra space that would be required for maintaining a stack during recursive
traversals.
- This can be crucial in resource-constrained environments or when dealing with large trees.
**Example:**
```plaintext
4
/\
2 6
/\/\
1 35 7
```
In a threaded binary tree, additional threads can be added to connect the in-order successor or predecessor of
each node.
Now, with these threads, an in-order traversal can be done without using recursion or a stack. Starting from the
leftmost node (1) and following the threads, the traversal would be: 1, 2, 3, 4, 5, 6, 7.
12. what is graph. the diff b/w tree anad graph. how to represent graph ( adjust matrix and adjency list)
A graph is a data structure that consists of a set of nodes (vertices) and a set of edges connecting these nodes.
Nodes represent entities, and edges represent relationships or connections between these entities. Graphs are
widely used to model various relationships in real-world scenarios, such as social networks, transportation
systems, and dependencies between tasks.
**Representation of a Graph:**
1. **Adjacency Matrix:**
- In an adjacency matrix, a 2D array is used to represent the graph.
- Rows and columns correspond to nodes, and the value at matrix[i][j] indicates whether there is an edge
between nodes i and j.
- Efficient for dense graphs but can be memory-intensive for sparse graphs.
**Example:**
```
012
+---------
0|0 1 1
1|1 0 1
2|1 1 0
```
2. **Adjacency List:**
- In an adjacency list, each node has a list of its neighbors.
- A list of lists or a dictionary is commonly used to represent the graph.
- Efficient for sparse graphs and consumes less memory compared to an adjacency matrix.
**Example:**
{
0: [1, 2],
1: [0, 2],
2: [0, 1]
}
13. The Diff B/W BFS and BFS.
14. what is spanning tree. what is MST and Following algorithm to finding MST
a) prim's algorithm
b) Kruskal’s algorithm
c) Dijkstra’s algorithm
d) Floyd-warshall algorithm.
A spanning tree of a connected, undirected graph is a subgraph that is a tree and includes all the vertices of the
original graph. It essentially forms a tree that spans all the vertices of the graph without forming any cycles.
a) Prim's Algorithm
- Start with an arbitrary vertex and grow the tree by adding the cheapest edge that connects a vertex in the tree to
a vertex outside the tree.
- Repeat this process until all vertices are included in the tree.
b) Kruskal's Algorithm:
- Sort all the edges in non-decreasing order of their weights.
- Iterate through the sorted edges and add each edge to the tree if it doesn't form a cycle with the edges already in
the tree.
- Repeat until the tree spans all vertices.
c) Dijkstra's Algorithm:
- Primarily used for finding the shortest path from a source vertex to all other vertices in a weighted graph.
- Not directly used for finding MST, but can be adapted to find a minimal spanning tree by repeatedly adding the
vertex with the smallest distance that is not already in the tree.
d) Floyd-Warshall Algorithm:
- Primarily used for all-pairs shortest path in a weighted graph.
- Not directly used for finding MST. It computes the shortest paths between all pairs of vertices, but it doesn't
directly produce a minimum spanning tree.