Data Structures Lab Exam Questions
Data Structures Lab Exam Questions
List ADT implementation using linked lists is advantageous when the list size is dynamic and frequent insertions or deletions at arbitrary positions are required, as linked lists allow for O(1) complexity operations at both ends. They avoid the need for reallocating memory, unlike arrays, which require allocating new memory slots for size expansion. Linked lists are more suitable for applications where efficient memory usage and flexible operations are necessary over direct index access, such as in certain types of cache implementations or undo functionalities in applications .
Both DFS and BFS have a time complexity of O(V + E), where V is the number of vertices and E is the number of edges. DFS is memory efficient, using O(h) space where h is the maximum depth of the tree, making it suitable for deep traversal with less branching. In contrast, BFS uses O(V) space as it stores all nodes at the current depth before moving on, which can be more memory-intensive but is effective for finding the shortest path in unweighted graphs. BFS is often preferred for shortest path solutions, while DFS can be used when the goal is to exhaustively explore paths .
Linear search has a time complexity of O(n), suitable for small or unsorted datasets, as it inspects each element sequentially. Binary search, with a time complexity of O(log n), is significantly faster on sorted datasets, as it repeatedly divides the search interval in half. Linear search is preferred when the dataset is unsorted or small, while binary search is ideal for large, sorted datasets, leveraging its logarithmic efficiency for rapid lookup .
A priority queue ADT is beneficial for applications requiring processing of elements based on priority rather than a strict FIFO or LIFO order, such as task scheduling or Dijkstra's algorithm. It allows efficient retrieval of the highest-priority element, typically in O(log n) time. However, priority queues can have overhead due to maintaining the heap structure, and can be inefficient for operations like finding non-prioritized elements or iterating through elements in arbitrary order .
Implementing BFS requires maintaining a queue to track nodes, which can become memory-intensive for large graphs. Additionally, managing visited nodes to avoid repeated processing is key to its efficiency and correctness. DFS poses challenges in recursion depth limitations, potentially causing stack overflow for deep recursion in dense graphs. Both methods require careful handling of edge cases, such as graphs with cycles or disconnected components, to ensure comprehensive traversal .
Converting infix to postfix using Stack ADT involves operators being pushed onto the stack and operands directly being appended to the output. This process has a time complexity of O(n), where n is the length of the expression. Evaluating a postfix expression also has a time complexity of O(n), as each operand is pushed onto the stack and popped for computation. Both processes are efficient with linear time complexities; however, the conversion process relies heavily on precedence rules, making it more complex to implement than evaluation, which is a straightforward linear scan .
Using a singly linked list for Stack ADT allows for efficient O(1) time complexity for push and pop operations, as operations are performed at the head. For Queue ADT, enqueuing and dequeuing operations are O(1) when maintaining pointers to both the head and tail. However, singly linked lists require more memory due to storage of pointers, and their sequential access can be slower compared to arrays, which affects performance when random access is required .
In a binary search tree (BST), insertion and deletion are relatively straightforward but can result in an imbalanced tree, leading to O(n) time complexities in the worst case. In contrast, AVL trees automatically maintain balance through rotations during insertion and deletion, ensuring O(log n) operations. Insertion in an AVL tree requires rotations to maintain this balance, which makes it more complex than in a BST. Deletion in an AVL tree is similarly complex, involving backtracking from the node of deletion to perform necessary rotations to ensure balance .
The implementation of List ADT using arrays involves pre-defining the size of the array, which can lead to inefficient memory utilization due to potential unused slots or the need for resizing. In contrast, a linked list dynamically allocates memory, with each element pointing to the next, allowing for flexible size adjustment and efficient memory use . However, accessing elements by index in an array is O(1) whereas, in a linked list, it is O(n) due to the need to traverse from the head to the desired element .
Selection sort is an in-place comparison sort with a time complexity of O(n^2), making it inefficient on large datasets compared to algorithms like mergesort or quicksort, which have average time complexities of O(n log n). It is relatively simple to implement and has the advantage of making fewer writes, which is useful for devices with limited memory write capabilities. However, its overall inefficiency in time complexity makes it less effective for general-purpose applications when compared to more sophisticated algorithms .