Bahria University, Lahore Campus
Department of Computer Sciences
Lab Journal 05
(Spring 2025)
Course: Data Structure and Algo. Lab
Course Code: CSL-221 Max Marks: 30
Faculty’s Name: Rizwan Khalid
Name: Taha Rehman Haroon Enroll No: 03-134241-054
. Implementation of Queues with Linked Structure and Priority Queue
In a linked queue, each node of the queue consists of two parts i.e. data part and the link part. Each
element of the queue points to its immediate next element in the memory. In the linked queue, there
are two pointers maintained in the memory i.e. front pointer and rear pointer.
The front pointer contains the address of the starting element of the queue while the rear pointer
contains the address of the last element of the queue. Insertion and deletions are performed at rear and
front end respectively. If front and rear both are NULL, it indicates that the queue is empty.
The linked representation of queue is shown in the following figure.
In a Queue data structure, we maintain two pointers, front and rear. The front points the first item of
queue and rear points to last item.
enQueue( ): This operation adds a new node after rear and moves rear to the next node.
deQueue( ): This operation removes the front node and moves front to the next node.
//Program 2 - To Implement Complete Functionality of Dynamic Queue.
#include<iostream>
#include<stdio.h>
using namespace std;
struct node
{
int data;
node *next;
}*front = NULL, *rear = NULL, *p = NULL, *np = NULL;
// Enqueue Function
void enqueue(int x)
{
np = new node;
np->data = x;
np->next = NULL;
if(front == NULL)
{
front = rear = np;
rear->next = NULL;
}
else
{
rear->next = np;
rear = np;
rear->next = NULL;
}
}
// Dequeue Function
int remove()
{
int x;
if(front == NULL)
{
cout<<"empty queue\n";
}
else
{
p = front;
x = p->data;
front = front->next;
delete(p);
return(x);
}
}
// Main Execution
int main()
{
int n, c = 0, x;
cout<<"Enter the number of values to be enqueued into queue\n";
cin>>n;
while (c < n)
{
cout<<"Enter the value to be entered into queue\n";
cin>>x;
enqueue(x);
c++;
cout<<"\n\nRemoved Values\n\n";
while(true)
{
if (front != NULL)
cout<<remove()<<endl;
else
break;
}
system("Pause");
}
OUTPUT: IMPLEMENT THIS CODE TO SEE OUTPUT
Tasks
Task #.1: Implement Queue class using Linked List. Add relevant functions to this class.
Code:
#include <iostream>
using namespace std;
class Node{
public:
int data;
Node * next;
Node (int val){
data = val;
next = NULL;
}
};
class Queue{
Node * head;
Node * tail;
public:
Queue(){
head = tail = NULL;
}
void enqueue(int data){
Node * newNode = new Node(data);
if (empty()){
head = tail = newNode;
}
else {
tail->next = newNode;
tail = newNode;
}
}
void dequeue(){
if (empty()){
cout << "Queue is empty"<<endl;
return;
else {
Node * temp = head;
head = head->next;
delete temp;
}
int front (){
if (empty()){
cout << "Queue is empty"<<endl;
return -1;
}
return head->data;
}
bool empty(){
return head == NULL;
}
void print (){
if (empty()){
cout << "Queue is empty"<<endl;
return;
}
while (!empty()){
cout << front() << " ";
dequeue();
}
cout << endl;
};
int main (){
Queue q;
q.enqueue(1);
q.enqueue(2);
q.enqueue(3);
q.print();
return 0;
}
Output:
Task #.2: Write a function template, ReverseQueue, which takes as a parameter a queue object to
reverse the elements of the queue.
Code:
#include <iostream>
using namespace std;
template <typename T>
class Node {
public:
T data;
Node* next;
Node(T val) {
data = val;
next = NULL;
}
};
template <typename T>
class Queue {
Node<T>* front;
Node<T>* rear;
public:
Queue() {
front = rear = NULL;
}
void enqueue(T data) {
Node<T>* newNode = new Node<T>(data);
if (rear == NULL) {
front = rear = newNode;
} else {
rear->next = newNode;
rear = newNode;
}
}
void dequeue() {
if (empty()) {
cout << "Queue is empty" << endl;
return;
}
Node<T>* temp = front;
front = front->next;
if (front == NULL) {
rear = NULL;
}
delete temp;
}
T peek() {
if (empty()) {
cout << "Queue is empty" << endl;
return T();
}
return front->data;
}
bool empty() {
return front == NULL;
}
void print() {
Node<T>* temp = front;
while (temp != NULL) {
cout << temp->data << " ";
temp = temp->next;
}
cout << endl;
}
void ReverseQueue() {
if (empty()) return;
T frontElement = peek();
dequeue();
ReverseQueue();
enqueue(frontElement);
}
};
int main() {
Queue<int> q;
q.enqueue(1);
q.enqueue(2);
q.enqueue(3);
q.enqueue(4);
q.enqueue(5);
cout << "Original Queue: ";
q.print();
q.ReverseQueue();
cout << "Reversed Queue: ";
q.print();
return 0;
}
Output:
Task #.3: Write a function template, ReverseQueue2, which takes as a parameter a queue object and
uses a stack object to reverse the elements of the queue.
Code:
#include <iostream>
using namespace std;
template <typename T>
class Node {
public:
T data;
Node* next;
Node(T val) {
data = val;
next = NULL;
}
};
template <typename T>
class Queue {
Node<T>* front;
Node<T>* rear;
public:
Queue() {
front = rear = NULL;
}
void enqueue(T data) {
Node<T>* newNode = new Node<T>(data);
if (rear == NULL) {
front = rear = newNode;
} else {
rear->next = newNode;
rear = newNode;
}
}
void dequeue() {
if (empty()) {
cout << "Queue is empty" << endl;
return;
}
Node<T>* temp = front;
front = front->next;
if (front == NULL) {
rear = NULL;
}
delete temp;
}
T peek() {
if (empty()) {
cout << "Queue is empty" << endl;
return T();
}
return front->data;
}
bool empty() {
return front == NULL;
}
void print() {
Node<T>* temp = front;
while (temp != NULL) {
cout << temp->data << " ";
temp = temp->next;
}
cout << endl;
}
template <typename U>
friend void ReverseQueue2(Queue<U>& q);
};
template <typename T>
class Stack {
Node<T>* top;
public:
Stack() {
top = NULL;
}
void push(T data) {
Node<T>* newNode = new Node<T>(data);
newNode->next = top;
top = newNode;
}
void pop() {
if (empty()) {
cout << "Stack is empty" << endl;
return;
}
Node<T>* temp = top;
top = top->next;
delete temp;
}
T peek() {
if (empty()) {
cout << "Stack is empty" << endl;
return T();
}
return top->data;
}
bool empty() {
return top == NULL;
}
};
template <typename T>
void ReverseQueue2(Queue<T>& q) {
Stack<T> s;
while (!q.empty()) {
s.push(q.peek());
q.dequeue();
}
while (!s.empty()) {
q.enqueue(s.peek());
s.pop();
}
}
int main() {
Queue<int> q;
q.enqueue(1);
q.enqueue(2);
q.enqueue(3);
q.enqueue(4);
q.enqueue(5);
cout << "Original Queue: ";
q.print();
ReverseQueue2(q);
cout << "Reversed Queue: ";
q.print();
return 0;
}
Output:
Task #.4: Add the operation queueCount to the class Queue, which returns the number of elements in
the queue.
CODE:
#include <iostream>
using namespace std;
class Node{
public:
int data;
Node * next;
Node (int val){
data = val;
next = NULL;
}
};
class Queue{
Node * head;
Node * tail;
public:
Queue(){
head = tail = NULL;
}
void enqueue(int data){
Node * newNode = new Node(data);
if (empty()){
head = tail = newNode;
}
else {
tail->next = newNode;
tail = newNode;
}
}
void dequeue(){
if (empty()){
cout << "Queue is empty"<<endl;
return;
else {
Node * temp = head;
head = head->next;
delete temp;
}
int front (){
if (empty()){
cout << "Queue is empty"<<endl;
return -1;
}
return head->data;
}
bool empty(){
return head == NULL;
}
void print (){
if (empty()){
cout << "Queue is empty"<<endl;
return;
}
while (!empty()){
cout << front() << " ";
dequeue();
}
cout << endl;
void count (){
if (empty()){
cout << "Queue is empty"<<endl;
return;
}
Node * temp = head;
int counter = 0;
while (temp != NULL){
counter ++;
temp = temp->next;
}
cout << "Number of elements: "<<counter<<endl;
}
};
int main (){
Queue q;
q.enqueue(1);
q.enqueue(2);
q.enqueue(3);
q.count();
q.enqueue(54);
q.count();
return 0;
}
OUTPUT:
Task #.5: Implement Priority Queue class using Linked List. Add relevant functions to this class
Code:
#include <iostream>
using namespace std;
class Node {
public:
int data;
int priority;
Node* next;
Node(int val, int pri) {
data = val;
priority = pri;
next = NULL;
}
};
class PriorityQueue {
Node* head;
public:
PriorityQueue() {
head = NULL;
}
void enqueue(int data, int priority) {
Node* newNode = new Node(data, priority);
if (empty() || priority < head->priority) {
newNode->next = head;
head = newNode;
}
else {
Node* temp = head;
while (temp->next != NULL && temp->next->priority <=
priority) {
temp = temp->next;
}
newNode->next = temp->next;
temp->next = newNode;
}
}
void dequeue() {
if (empty()) {
cout << "Queue is empty" << endl;
return;
}
Node* temp = head;
head = head->next;
delete temp;
}
int peek() {
if (empty()) {
cout << "Queue is empty" << endl;
return -1;
}
return head->data;
}
bool empty() {
return head == NULL;
}
void print() {
if (empty()) {
cout << "Queue is empty" << endl;
return;
}
Node* temp = head;
while (temp != NULL) {
cout << "(" << temp->data << ", " << temp->priority << ") ";
temp = temp->next;
}
cout << endl;
}
};
int main() {
PriorityQueue pq;
pq.enqueue(3, 3);
pq.enqueue(1, 1);
pq.enqueue(2, 2);
pq.enqueue(4, 0);
cout << "Priority Queue: ";
pq.print();
cout << "Front element (highest priority): " << pq.peek() << endl;
pq.dequeue();
cout << "After dequeue: ";
pq.print();
return 0;
}
Output: