0% found this document useful (0 votes)
12 views23 pages

Data Structure Using C++ (Unit 02)

The document provides an overview of queues and linked lists as fundamental data structures in computer science. It explains the definition, characteristics, types, and operations of queues, including FIFO principles and various queue types like circular and priority queues. Additionally, it discusses linked lists, detailing their structure, types, and operations such as insertion and deletion.

Uploaded by

preethivmadappa
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
12 views23 pages

Data Structure Using C++ (Unit 02)

The document provides an overview of queues and linked lists as fundamental data structures in computer science. It explains the definition, characteristics, types, and operations of queues, including FIFO principles and various queue types like circular and priority queues. Additionally, it discusses linked lists, detailing their structure, types, and operations such as insertion and deletion.

Uploaded by

preethivmadappa
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 23

Unit 02

Chapter = 1, QUEUES
Definition:
A Queue is defined as a linear data structure that is open at both ends and the
operations are performed in First in First Out (FIFO) order.
We define a queue to be a list in which all additions to the list are made at one end,
and all deletions from the list are made at the other end. The element which is first pushed
into the order, the operation is first performed on that.
The Queue Data Structure is a fundamental concept in computer science used for
storing and managing data in a specific order.
• It follows the principle of "First in, First out" (FIFO), where the first element added
to the queue is the first one to be removed.
• Queues are commonly used in various algorithms and applications for their simplicity
and efficiency in managing data flow.

FIFO Principle of Queue Data Structure:


• A Queue is like a line waiting to purchase tickets, where the first person in line is the
first person served. (i.e. First Come First Serve).
• Position of the entry in a queue ready to be served, that is, the first entry that will be
removed from the queue, is called the front of the queue(sometimes, head of the
queue). Similarly, the position of the last entry in the queue, that is, the one most
recently added, is called the rear (or the tail) of the queue.
Representation of Queue Data Structure
We know that a queue can be accessed from both sides i.e. at the front for deletion and
back or rear for insertion.

• Queue: the name of the array storing queue elements.


• Front: the index where the first element is stored in the array representing the
queue.
• Rear: the index where the last element is stored in an array representing the
queue.

Characteristics of Queue:
• Queue can handle multiple data.
• We can access both ends.
• They are fast and flexible.
Types of Queue Data Structure:

Queue data structure can be classified into 4 types:


1. Simple Queue or Liner Queue: In Linear Queue, an insertion takes place from one
end while the deletion occurs from another end. The end at which the insertion takes
place is known as the rear end, and the end at which the deletion takes place is known
as front end. It strictly follows the FIFO rule.

The major drawback of using a linear Queue is that insertion is done only from
the rear end. If the first three elements are deleted from the Queue, we cannot insert
more elements even though the space is available in a Linear Queue. In this case, the
linear Queue shows the overflow condition as the rear is pointing to the last element of
the Queue.
2. Circular Queue: This is a special type of queue where the last position is connected
back to the first position. Here also the operations are performed in FIFO order.

In Circular Queue, all the nodes are represented as circular. It is similar to the
linear Queue except that the last element of the queue is connected to the first element.
It is also known as Ring Buffer, as all the ends are connected to another end. The
representation of circular queue is shown in the below image -

The drawback that occurs in a linear queue is overcome by using the circular
queue. If the empty space is available in a circular queue, the new element can be
added in an empty space by simply incrementing the value of rear. The main
advantage of using the circular queue is better memory utilization.

3. Double-Ended Queue (Dequeue): In Deque or Double Ended Queue, insertion and


deletion can be done from both ends of the queue either from the front or rear. It
means that we can insert and delete elements from both front and rear ends of the
queue. Deque can be used as a palindrome checker means that if we read the string
from both ends, then the string would be the same.
Deque can be used both as stack and queue as it allows the insertion and
deletion operations on both ends. Deque can be considered as stack because stack
follows the LIFO (Last In First Out) principle in which insertion and deletion both can
be performed only from one end. And in deque, it is possible to perform both insertion
and deletion from one end, and Deque does not strictly follow the FIFO principle.

The representation of the deque is shown in the below image -


There are two types of deque that are discussed as follows -

o Input restricted deque - As the name implies, in input restricted queue, insertion
operation can be performed at only one end, while deletion can be performed from
both ends.

o Output restricted deque - As the name implies, in output restricted queue, deletion
operation can be performed at only one end, while insertion can be performed from
both ends.

4. Priority Queue: It is a special type of queue in which the elements are arranged based
on the priority. It is a special type of queue data structure in which every element has a
priority associated with it. Suppose some elements occur with the same priority, they
will be arranged according to the FIFO principle. The representation of priority queue
is shown in the below image -

Insertion in priority queue takes place based on the arrival, while deletion in the
priority queue occurs based on the priority. Priority queue is mainly used to implement
the CPU scheduling algorithms.
There are two types of priority queue that are discussed as follows -

o Ascending priority queue - In ascending priority queue, elements can be inserted in


arbitrary order, but only smallest can be deleted first. Suppose an array with elements
7, 5, and 3 in the same order, so, insertion can be done with the same sequence, but the
order of deleting the elements is 3, 5, 7.
o Descending priority queue - In descending priority queue, elements can be inserted
in arbitrary order, but only the largest element can be deleted first. Suppose an array
with elements 7, 3, and 5 in the same order, so, insertion can be done with the same
sequence, but the order of deleting the elements is 7, 5, 3.

Basic Operations in Queue Data Structure:


Some of the basic operations for Queue in Data Structure are:
• Enqueue: Adds (or stores) an element to the end of the queue...
• Dequeue: Removal of elements from the queue.
• Peek or front: Acquires the data element available at the front node of the
queue without deleting it.
• rear: This operation returns the element at the rear end without removing it.
• isFull: Validates if the queue is full.
• isEmpty: Checks if the queue is empty.
1. Enqueue Operation in Queue Data Structure:
Enqueue () operation in Queue adds (or stores) an element to the end of the queue.
The following steps should be taken to enqueue (insert) data into a queue:
• Step 1: Check if the queue is full.
• Step 2: If the queue is full, return overflow error and exit.
• Step 3: If the queue is not full, increment the rear pointer to point to the next empty
space.
• Step 4: Add the data element to the queue location, where the rear is pointing.
• Step 5: return success.
Algorithm of Enqueue
procedure enqueue(data)
if queue is full
return overflow
endif
rear=rear + 1
queue[rear] = data
return true
end procedure
2. Dequeue Operation in Queue Data Structure:
Removes (or access) the first element from the queue.
The following steps are taken to perform the dequeue operation:
• Step 1: Check if the queue is empty.
• Step 2: If the queue is empty, return the underflow error and exit.
• Step 3: If the queue is not empty, access the data where the front is pointing.
• Step 4: Increment the front pointer to point to the next available data element.
• Step 5: The Return success.

Algorithm for enqueue operation


Procedure dequeue
if queue is empty
return underflow
endif
data = queue[front]
end procedure
Applications of Queue Data Structure

1. Task Scheduling: A queue is an ideal data structure for task scheduling, which lets
you perform all the tasks in order. Initially, all the tasks are pushed to the end of the
queue. We can pick the task at the front of the queue and execute it. Once you
complete the task, it is removed from the queue, and you select the next task. This
process will continue until the queue is empty.
2. Batch Processing: Similar to task scheduling, you can use a queue data structure
when you need to perform a large number of tasks in batches. Queue helps to
complete all the tasks in order without leaving a task unprocessed.
3. Event Handling: In event handling, a queue data structure stores all the events that
have occurred but are yet to be processed by the system. If a new event occurs, it is
pushed to the end of the queue, and the system then processes the event from the front
of the queue and removes it once handled.
4. Message Buffering: Message buffer stores the messages in the order they arrive and
processes them one by one. The queue is an ideal data structure because of its FIFO
(First In, First Out) property.
5. Traffic Management: Circular queues are used to manage the traffic lights in a
traffic management system for switching the traffic lights one by one, in order.
6. Application of queues in operating systems are:
• It helps in First Come, First Serve to schedule.
• It also makes CPU scheduling easier.
• It is used in memory management.
7. Applications of Queue in Networks are:
• Queues are used in routers and switches.
• It is used in packet switching.
8. Some Other Useful Applications of Queue
• WhatsApp uses a queue to queue up the messages in the WhatsApp server if the
recipient’s internet connection is turned off.
• It is used in music applications to queue up a new song in a playlist.
• It is used in traffic management to manage traffic lights.
Chapter = 2, Linked List
Definition:

A linked list is a linear data structure which can store a collection of "nodes"
connected together via links i.e., pointers.

• Linked lists nodes are not stored at a contiguous location, rather they are linked
using pointers to the different memory locations. A node consists of the data
value and a pointer to the address of the next node within the linked list.
• A linked list is a dynamic linear data structure whose memory size can be
allocated or de-allocated at run time based on the operation insertion or
deletion, this helps in using system memory efficiently. Linked lists can be used
to implement various data structures like a stack, queue, graph, hash maps, etc.

A linked list starts with a head node which points to the first node. Every node
consists of data which holds the actual data (value) associated with the node and a next
pointer which holds the memory address of the next node in the linked list. The last
node is called the tail node in the list which points to null indicating the end of the list.

Types of Linked Lists

There are four key types of linked lists:

• Singly linked lists


• Doubly linked lists
• Circular linked lists
• Circular doubly linked lists
Singly Linked List
Singly linked lists contain two "buckets" in one node; one bucket holds the data and
the other bucket holds the address of the next node of the list. Traversals can be done in one
direction only as there is only a single link between two nodes of the same list.

Example:

Doubly Linked Lists


Doubly Linked Lists contain three "buckets" in one node; one bucket holds the
data and the other buckets hold the addresses of the previous and next nodes in the list.
The list is traversed twice as the nodes in the list are connected to each other from both
sides.

Example:

Circular Linked Lists


Circular linked lists can exist in both singly linked list and doubly linked list.

Since the last node and the first node of the circular linked list are connected, the traversal in
this linked list will go on forever until it is broken.
Example:

Circular Doubly Linked List:


A circular doubly linked list is a mixture of a doubly linked list and a circular linked
list. Like the doubly linked list, it has an extra pointer called the previous pointer, and similar
to the circular linked list, its last node points at the head node. This type of linked list is the
bi-directional list. So, you can traverse it in both directions.
Chapter = 3, Singly Linked List

A singly linked list is a fundamental data structure, it consists of nodes where each node
contains a data field and a reference to the next node in the linked list. The next of the last
node is null, indicating the end of the list. Linked Lists support efficient insertion and
deletion operations.
Understanding Node Structure
In a singly linked list, each node consists of two parts: data and a pointer to the next node.
This structure allows nodes to be dynamically linked together, forming a chain-like
sequence.

// Definition of a Node in a singly linked list


struct Node {

// Data part of the node


int data;

// Pointer to the next node in the list


Node* next;

// Constructor to initialize the node with data


Node(int data)
{
this->data = data;
this->next = nullptr;
}
};

In this example, the Node class contains an integer data field (data) to store the information
and a pointer to another Node (next) to establish the link to the next node in the list.
Operations on Singly Linked List
• Traversal
• Searching
• Length
• Insertion:
1. Insert at the beginning
2. Insert at the end
3. Insert at a specific position
• Deletion:
1. Delete from the beginning
2. Delete from the end
3. Delete a specific node

Insertion in Singly Linked List


Insertion is a fundamental operation in linked lists that involves adding a new node
to the list. There are several scenarios for insertion:

Insertion at the Beginning of Singly Linked List:

Step-by-step approach:

• Create a new node with the given value.


• Set the next pointer of the new node to the current head.
• Move the head to point to the new node.
• Return the new head of the linked list.
C++ Program to insert the node at the beginning of Linked List
#include <iostream.h>
#include <conio.h>
struct Node {
int data;
Node* next;
Node(int new_data) {
data = new_data;
next = NULL;
}
};
Node* insertAtFront(Node* head, int new_data) {
Node* new_node = new Node(new_data);
new_node->next = head;
return new_node;
}
void printList(Node* head) {
Node* curr = head;
while (curr != NULL) {
cout << " " << curr->data;
curr = curr->next;
}
cout << endl;
}
void main() {
clrscr();
Node* head = new Node(2);
head->next = new Node(3);
head->next->next = new Node(4);
head->next->next->next = new Node(5);
cout << "Original Linked List:";
printList(head);
cout << "After inserting Nodes at the front:";
int data = 1;
head = insertAtFront(head, data);
printList(head);
getch();
}

Output

Original Linked List: 2 3 4 5


After inserting Nodes at the front: 1 2 3 4 5

Deletion at the End of Singly Linked List:

To delete the last node, traverse the list until the second-to-last node and update its next
field to None.

Step-by-step approach:
• Check if the head is NULL.
o If it is, return NULL (the list is empty).
• Check if the head's next is NULL (only one node in the list).
o If true, delete the head and return NULL.
• Traverse the list to find the second last node (second_last).
• Delete the last node (the node after second_last).
• Set the next pointer of the second last node to NULL.
• Return the head of the linked list.
C++ program to delete the last node of linked list
#include <iostream.h>
#include <conio.h>
struct Node {
int data;
Node* next;
Node(int data)
: data(data), next(NULL)
{
}
};
Node* removeLastNode(struct Node* head) {
if (head == NULL) {
return NULL;
}
if (head->next == NULL) {
delete head;
return NULL;
}
Node* second_last = head;
while (second_last->next->next != NULL) {
second_last = second_last->next;
}
delete (second_last->next);
second_last->next = NULL;
return head;
}
void printList(Node* head) {
while (head != NULL) {
cout << head->data;
if (head->next != NULL) {
cout << ", ";
}
head = head->next;
}
cout << endl;
}
void main() {
clrscr();
Node* head = new Node(1);
head->next = new Node(2);
head->next->next = new Node(3);
head->next->next->next = new Node(4);
head->next->next->next->next = new Node(5);
cout << "Original list: ";
printList(head);
head = removeLastNode(head);
cout << "List after removing the last node: ";
printList(head);
getch();
}
Output
Original list: 1,2,3,4,5

List after removing the last node: 1,2,3,4


Chapter = 4, Doubly Linked List

Memory Representation of a Singly Linked List


A singly linked list is a linear data structure composed of nodes that are dynamically
allocated in memory. Each node has two parts:
1. Data Field: Contains the actual data stored in the node.
2. Pointer Field: Contains the address of the next node in the sequence.
Structure of a Node
In C++, a node can be represented using a struct:
struct Node {
int data; // Data field
struct Node* next; // Pointer to the next node
};
Each node is dynamically allocated during the program's execution and may be stored in
non-contiguous memory locations.
Unlike arrays, where elements are stored in contiguous memory locations, linked lists
allocate memory dynamically for each node. This means that each node can be located
anywhere in the memory and they are connected via pointers.

Memory Layout
Consider a singly linked list storing three elements: 12 13 15 18 NULL.
Its memory representation can be visualized as:
Address Data Next Pointer

150 12 250

250 13 350

350 15 450

450 18 NULL

1. Each node's Data field contains the actual value.


2. Each node's Next Pointer field stores the memory address of the next node.
3. The last node's Next Pointer is NULL, signalling the end of the list.

Here:

• 1001, 2003, and 3005 are memory addresses of the respective nodes.
• The Next Pointer in each node holds the address of the next node in the list.
• The Next Pointer of the last node is NULL, indicating the end of the list.

Key Points

1. The head pointer of the list stores the memory address of the first node.
2. Traversing the list involves moving from one node to the next by following the Next
pointers until NULL is encountered.
3. Memory is dynamically allocated for each node during runtime, allowing the list size
to grow or shrink as needed.
4. Memory representation is not contiguous, meaning the nodes can be scattered across
the memory.

150 250 350 450

This structure is efficient for insertion and deletion operations but requires extra memory for
storing the pointers.
Memory Representation of a Doubly Linked List

A doubly linked list in C++ is a linear data structure where each node contains three
components:

1. Data: Holds the value or data of the node.


2. Pointer to the next node: Points to the next node in the list.
3. Pointer to the previous node: Points to the previous node in the list.

This structure allows traversal in both forward and backward directions.

Here’s how memory representation works:

1. Node Structure

Each node in the doubly linked list contains:

• A data field to store the node's value.


• A next pointer to the next node.
• A prev pointer to the previous node.

In memory, these nodes are stored in non-contiguous locations. The prev and next pointers
create the links.

struct Node {
int data; // Data part
Node* prev; // Pointer to the previous node
Node* next; // Pointer to the next node
};
2. Head and Tail Pointers

• Head Pointer: Points to the first node in the list.


• Tail Pointer: Points to the last node in the list.

Both pointers are used to manage the list.


3. Memory Layout Example

In this diagram, -1 represents the NULL value, indicating the start or end of the list. For
example, the first node (A) has its previous address as -1, and the last node (D) has its next
address as -1, forming the structure -1 ← A ⇆ B ⇆ C ⇆ D → -1.
4.Memory representation of doubly linked list:
For example:

5. Key Points

• Each node is allocated memory dynamically using new.


• The prev pointer of the first node is nullptr.
• The next pointer of the last node is nullptr.
• Each node has bidirectional links, making traversal more flexible but increasing
memory usage compared to a singly linked list.

Applications of linked list in computer science:


1. Implementation of stacks and queues
2. Implementation of graphs: Adjacency list representation of graphs is the most
popular which uses a linked list to store adjacent vertices.
3. Dynamic memory allocation: We use a linked list of free blocks.
4. Maintaining a directory of names
5. Performing arithmetic operations on long integers
6. Manipulation of polynomials by storing constants in the node of the linked list
7. Representing sparse matrices
Applications of linked list in the real world:
1. Image viewer – Previous and next images are linked and can be accessed by the
next and previous buttons.
2. Previous and next page in a web browser – We can access the previous and next
URL searched in a web browser by pressing the back and next buttons since they
are linked as a linked list.
3. Music Player – Songs in the music player are linked to the previous and next
songs. So, you can play songs either from starting or ending of the list.
4. GPS navigation systems- Linked lists can be used to store and manage a list of
locations and routes, allowing users to easily navigate to their desired destination.
5. Robotics- Linked lists can be used to implement control systems for robots,
allowing them to navigate and interact with their environment.
6. Task Scheduling- Operating systems use linked lists to manage task scheduling,
where each process waiting to be executed is represented as a node in the list.
7. Image Processing- Linked lists can be used to represent images, where each pixel
is represented as a node in the list.
8. File Systems- File systems use linked lists to represent the hierarchical structure
of directories, where each directory or file is represented as a node in the list.
9. Symbol Table- Compilers use linked lists to build a symbol table, which is a data
structure that stores information about identifiers used in a program.
10.Undo/Redo Functionality- Many software applications implement undo/redo
functionality using linked lists, where each action that can be undone is
represented as a node in a doubly linked list.
11.Speech Recognition- Speech recognition software uses linked lists to represent
the possible phonetic pronunciations of a word, where each possible
pronunciation is represented as a node in the list.
12.Polynomial Representation- Polynomials can be represented using linked lists,
where each term in the polynomial is represented as a node in the list.
13.Simulation of Physical Systems- Linked lists can be used to simulate physical
systems, where each element in the list represents a discrete point in time and the
state of the system at that time.

You might also like