# 1. Introduction

A Priority Queue is a special type of queue in which each element is associated with a priority. Elements with higher priorities are served before elements with lower priorities. In this tutorial, we'll implement a basic Priority Queue in TypeScript.

# 2. Program Overview

We'll implement a Priority Queue with the following features:

- Enqueuing items with a priority.

- Dequeuing the highest priority item.

- Peeking at the item with the highest priority without removing it.

# 3. Code Program

``````// Define the QueueItem class to hold the data and its priority
class QueueItem {
data: any;
priority: number;

constructor(data: any, priority: number) {
this.data = data;
this.priority = priority;
}
}

// Define the PriorityQueue class
class PriorityQueue {
items: QueueItem[] = [];

// Enqueue a new item into the Priority Queue
enqueue(data: any, priority: number): void {
const newItem = new QueueItem(data, priority);

for (let i = 0; i < this.items.length; i++) {
if (newItem.priority < this.items[i].priority) {
this.items.splice(i, 0, newItem);
break;
}
}

this.items.push(newItem);
}
}

// Dequeue the highest priority item from the Priority Queue
dequeue(): any {
if (this.isEmpty()) return "Underflow";
return this.items.shift()?.data;
}

// Peek at the highest priority item without dequeuing
peek(): any {
if (this.isEmpty()) return "Empty Queue";
return this.items[0].data;
}

// Helper method to check if the Priority Queue is empty
isEmpty(): boolean {
return this.items.length == 0;
}
}

// Test the PriorityQueue class
const pq = new PriorityQueue();
console.log("Peek at highest priority item:", pq.peek());
console.log("Dequeue highest priority item:", pq.dequeue());
console.log("Peek at highest priority item:", pq.peek());
``````

# 4. Step By Step Explanation

1. We start by defining the QueueItem class:

- It contains two properties: data and priority. The data holds the actual data and the priority holds the priority of the item. A lower numeric value indicates a higher priority.

2. Next, we define the PriorityQueue class with the following methods:

a. enqueue: Adds a new item to the Priority Queue.

- We create a new QueueItem instance with the provided data and priority.

- We loop through the queue to find the correct position for the new item based on its priority and insert it.

- If the item has the lowest priority (or the queue is empty), it's simply added to the end.

3. dequeue: Removes and returns the highest priority item from the Priority Queue.

- It checks if the queue is empty. If it is, it returns an "Underflow" message.

- Otherwise, it removes and returns the first item from the queue.

4. peek: This allows us to see the highest priority item without removing it from the queue.

- If the queue is empty, it returns an "Empty Queue" message.

- Otherwise, it returns the data of the first item.

5. isEmpty: A helper method to check if the Priority Queue is empty.

- Returns true if the queue is empty and false otherwise.

6. Lastly, we test our Priority Queue by:

- Creating an instance of the PriorityQueue class.

- Enqueuing some tasks with their respective priorities.

- Peeking at the highest priority item and dequeuing items.

This TypeScript Priority Queue implementation uses an array to store the items and is best suited for small datasets. For larger datasets, using a binary heap can provide better performance.

Note: Remember that a smaller priority number means a higher actual priority in this implementation.