Reactive Priority Queue in Vue.js with TypeScript
This challenge asks you to implement a priority queue within a Vue.js component using TypeScript. Priority queues are essential data structures for scenarios requiring elements to be processed in order of their priority (e.g., task scheduling, event handling, Dijkstra's algorithm). This exercise combines data structure implementation with reactive Vue.js component management.
Problem Description
You need to create a Vue.js component that encapsulates a priority queue. The priority queue should allow users to:
- Enqueue: Add elements to the queue, each with an associated priority (a number). Lower numbers represent higher priority.
- Dequeue: Remove and return the element with the highest priority (lowest priority number).
- Peek: View the element with the highest priority without removing it.
- IsEmpty: Check if the queue is empty.
- Size: Get the number of elements in the queue.
The component should be reactive. Changes to the queue (enqueue, dequeue) should automatically update the component's displayed state. The component should expose these operations as methods. The queue's contents should be displayed in a user-friendly format within the component's template.
Key Requirements:
- TypeScript: The entire implementation must be in TypeScript.
- Vue.js Component: The priority queue must be encapsulated within a Vue.js component.
- Reactivity: Changes to the queue must be reactive and reflected in the component's template.
- Priority: Lower numerical values represent higher priority.
- Error Handling: Handle edge cases gracefully (e.g., attempting to dequeue from an empty queue).
Expected Behavior:
- Enqueueing an element adds it to the queue, maintaining priority order.
- Dequeueing removes the highest priority element.
- Peeking returns the highest priority element without removing it.
- The component's template displays the queue's contents in a clear and organized manner.
- The component provides methods for all the required operations.
- The component handles empty queue scenarios appropriately.
Edge Cases to Consider:
- Enqueueing elements with the same priority. (Maintain insertion order for elements with equal priority).
- Dequeueing from an empty queue. (Return
undefinedor throw an error – clearly document the chosen behavior). - Large number of elements in the queue (consider performance implications).
Examples
Example 1:
Input: Initial queue is empty. Enqueue("Task A", 1), Enqueue("Task B", 3), Enqueue("Task C", 2)
Output: Queue contents displayed as: ["Task A", "Task C", "Task B"]
Explanation: "Task A" has the highest priority (1), followed by "Task C" (2), and then "Task B" (3).
Example 2:
Input: Queue contains ["Task A", "Task C", "Task B"]. Dequeue()
Output: Returns "Task A". Queue contents displayed as: ["Task C", "Task B"]
Explanation: "Task A" was the highest priority element and was removed.
Example 3: (Edge Case - Empty Queue)
Input: Queue is empty. Dequeue()
Output: Returns undefined (or throws an error, as documented).
Explanation: Attempting to dequeue from an empty queue results in no element to return.
Constraints
- Time Complexity: Enqueue should be O(log n), Dequeue, Peek, IsEmpty, and Size should be O(1).
- Space Complexity: The priority queue should use a reasonable amount of memory, proportional to the number of elements.
- Input Format: Priorities must be numbers. Element values can be any type.
- Vue.js Version: Use Vue 3.
- Component Structure: The component should be well-structured and easy to understand.
Notes
- Consider using a heap data structure (e.g., a binary heap) to efficiently implement the priority queue. Libraries are allowed, but implementing the heap yourself is preferred for this exercise.
- Vue's reactivity system can be leveraged to automatically update the component's template when the queue's contents change. Use
reforreactiveappropriately. - Think about how to handle errors gracefully, especially when attempting to dequeue from an empty queue. Document your chosen error handling strategy.
- Focus on creating a clean, well-documented, and testable component. While formal unit tests are not required, consider how you would test the component's functionality.