You are on page 1of 20

Introduction:

This report aims to provide an overview of the implementation of four fundamental data structures:
Stack, Queue, Linked List, and Doubly Linked List. Each data structure serves a specific purpose and
offers different advantages in terms of data organization and operations. The report will cover the
implementation details, key features, and functions included in each data structure.

1. Stack Implementation: The stack is a Last-In-First-Out (LIFO) data structure that follows a
simple principle: the last element inserted is the first one to be removed. The stack can be
implemented using an array or a linked list. The stack implementation includes the following
functions:

 push(Element): Inserts an element at the top of the stack.


 pop(): Removes and returns the top element from the stack.
 peek(): Retrieves the value of the top element without removing it.
 isEmpty(): Checks if the stack is empty.
 isFull(): Checks if the stack is full (applicable to array-based implementation).

3. Queue Implementation: The queue is a First-In-First-Out (FIFO) data structure that operates on
the principle of processing elements in the order they were added. The queue can be implemented
using an array or a linked list. The queue implementation includes the following functions:

 enqueue(Element): Inserts an element at the rear of the queue.


 dequeue(): Removes and returns the front element from the queue.
 peek(): Retrieves the value of the front element without removing it.
 isEmpty(): Checks if the queue is empty.
 isFull(): Checks if the queue is full (applicable to array-based implementation).

4. Linked List Implementation: A linked list is a linear data structure consisting of nodes, where
each node contains a data element and a reference to the next node. Linked lists provide dynamic
memory allocation and flexibility in terms of inserting, removing, and accessing elements. The linked
list implementation includes the following functions:
 insertAtBeginning(Element): Inserts an element at the beginning of the linked list.
 insertAtEnd(Element): Inserts an element at the end of the linked list.
 insertAfter(Node, Element): Inserts an element after a specified node in the linkedlist.
 delete(Node): Deletes a specified node from the linked list.
 search(Element): Searches for a given element in the linked list.
 display(): Displays the elements of the linked list.
5. Doubly Linked List Implementation: A doubly linked list is an extension of the linked list,
where each node contains references to both the next and previous nodes. This bidirectional link
allows for efficient traversal in both directions. The doubly linked list implementation includes the
following functions:
 insertAtBeginning(Element): Inserts an element at the beginning of the doubly
linked list.
 insertAtEnd(Element): Inserts an element at the end of the doubly linked list.
 insertAfter(Node, Element): Inserts an element after a specified node in the doubly
linked list.
 delete(Node): Deletes a specified node from the doubly linked list.
 search(Element): Searches for a given element in the doubly linked list.
 displayForward(): Displays the elements of the doubly linked list in the forward direction.
 displayBackward(): Displays the elements of the doubly linked list in the backward
direction.

Conclusion:
In conclusion, this report has provided an overview of the implementation details for four essential
data structures: Stack, Queue, Linked List, and Doubly Linked List. Each data structure has its own
unique characteristics, and their implementations involve defining the appropriate structures,
initializing them correctly, and implementing the necessary functions based on the desired
functionality. Understanding these implementations and their underlying principles is crucial for
efficient data manipulation and algorithm design.
CODE:

#include <iostream>
using namespace std;

struct Node {
int data;
Node* next;
};

class LinkedList {
private:
Node* head;

public:
LinkedList() : head(NULL) {}

void insert(int value) {


Node* newNode = new Node;
newNode->data = value;
newNode->next = NULL;

if (head == NULL) {
head = newNode;
} else {
Node* temp = head;
while (temp->next != NULL) {
temp = temp->next;
}
temp->next = newNode;
}
}

void remove(int value) {


if (head == NULL) {
cout << "List is empty!" << endl;
return;
}

if (head->data == value) {
Node* temp = head;
head = head->next;
delete temp;
cout << "Node with value " << value << " deleted." << endl;
return;
}

Node* temp = head->next;


Node* prev = head;
while (temp != NULL) {
if (temp->data == value) {
prev->next = temp->next;
delete temp;
cout << "Node with value " << value << " deleted." << endl;
return;
}
prev = temp;
temp = temp->next;
}

cout << "Node with value " << value << " not found." << endl;
}

bool search(int value) {


Node* temp = head;
while (temp != NULL) {
if (temp->data == value) {
return true;
}
temp = temp->next;
}
return false;
}

void update(int oldValue, int newValue) {


Node* temp = head;
while (temp != NULL) {
if (temp->data == oldValue) {
temp->data = newValue;
cout << "Value updated." << endl;
return;
}
temp = temp->next;
}
cout << "Node with value " << oldValue << " not found." << endl;
}

int count() {
int count = 0;
Node* temp = head;
while (temp != NULL) {
count++;
temp = temp->next;
}
return count;
}

void display() {
Node* temp = head;
while (temp != NULL) {
cout << temp->data << " ";
temp = temp->next;
}
cout << endl;
}
};

const int MAX_SIZE = 100;

class Stack {
private:
int arr[MAX_SIZE];
int top;

public:
Stack() {
top = -1;
}

bool isEmpty() {
return top == -1;
}

bool isFull() {
return top == MAX_SIZE - 1;
}

void push(int value) {


if (isFull()) {
cout << "Stack Overflow. Cannot push element." << endl;
return;
}
top++;
arr[top] = value;
cout << "Pushed " << value << " to the stack." << endl;

void pop() {
if (isEmpty()) {
cout << "Stack Underflow. Cannot pop element." << endl;
return;
}

int poppedValue = arr[top];


top--;
cout << "Popped " << poppedValue << " from the stack." << endl;
}

int peek() {
if (isEmpty()) {
cout << "Stack is empty." << endl;
return -1;
}

return arr[top];
}

bool search(int value) {


if (isEmpty()) {
cout << "Stack is empty. Cannot perform search." << endl;
return false;
}

for (int i = 0; i <= top; i++) {


if (arr[i] == value) {
cout << value << " found at position " << i << " from the top of the stack." << endl;
return true;
}
}

cout << value << " not found in the stack." << endl;
return false;
}
void update(int oldValue, int newValue) {
if (isEmpty()) {
cout << "Stack is empty. Cannot perform update." << endl;
return;
}

for (int i = 0; i <= top; i++) {


if (arr[i] == oldValue) {
arr[i] = newValue;
cout << "Updated " << oldValue << " to " << newValue << " in the stack." << endl;
return;
}
}

cout << "Value " << oldValue << " not found in the stack. Update failed." << endl;
}
void display() {
if (isEmpty()) {
cout << "Stack is empty. Nothing to display." << endl;
return;
}

cout << "Stack elements: ";


for (int i = top; i >= 0; i--) {
cout << arr[i] << " ";
}
cout << endl;
}
};
struct DNode {
int data;
DNode* prev;
DNode* next;
};

class DoublyLinkedList {
private:
DNode* head;

public:
DoublyLinkedList() {
head = NULL;
}
bool isEmpty() {
return head == NULL;
}

void insert(int value) {


DNode* newNode = new DNode();
newNode->data = value;
newNode->prev = NULL;
newNode->next = NULL;

if (isEmpty()) {
head = newNode;
} else {
DNode* current = head;
while (current->next != NULL) {
current = current->next;
}
current->next = newNode;
newNode->prev = current;
}

cout << "Inserted " << value << " into the doubly linked list." << endl;
}

void remove(int value) {


if (isEmpty()) {
cout << "Doubly linked list is empty. Cannot perform removal." << endl;
return;
}

DNode* current = head;


while (current != NULL) {
if (current->data == value) {
if (current == head) {
head = current->next;
if (head != NULL) {
head->prev = NULL;
}
} else {
current->prev->next = current->next;
if (current->next != NULL) {
current->next->prev = current->prev;
}
}
cout << "Removed " << value << " from the doubly linked list." << endl;
delete current;
return;
}

current = current->next;
}

cout << "Value " << value << " not found in the doubly linked list. Removal failed." << endl;
}

bool search(int value) {


if (isEmpty()) {
cout << "Doubly linked list is empty. Cannot perform search." << endl;
return false;
}

DNode* current = head;


while (current != NULL) {
if (current->data == value) {
cout << value << " found in the doubly linked list." << endl;
return true;
}
current = current->next;
}

cout << value << " not found in the doubly linked list." << endl;
return false;
}

void update(int oldValue, int newValue) {


if (isEmpty()) {
cout << "Doubly linked list is empty. Cannot perform update." << endl;
return;
}

DNode* current = head;


while (current != NULL) {
if (current->data == oldValue) {
current->data = newValue;
cout << "Updated " << oldValue << " to " << newValue << " in the doubly linked list." << endl;
return;
}
current = current->next;
}

cout << "Value " << oldValue << " not found in the doubly linked list. Update failed." << endl;
}
void reverse() {
if (isEmpty()) {
cout << "Doubly linked list is empty. Cannot perform reversal." << endl;
return;
}

DNode* current = head;


DNode* temp = NULL;

while (current != NULL) {


temp = current->prev;
current->prev = current->next;
current->next = temp;

current = current->prev;
}

if (temp != NULL) {
head = temp->prev;
}

cout << "Doubly linked list reversed." << endl;


}

void display() {
if (isEmpty()) {
cout << "Doubly linked list is empty. Nothing to display." << endl;
return;
}

cout << "Doubly linked list: ";


DNode* current = head;
while (current != NULL) {
cout << current->data << " ";
current = current->next;
}
cout << endl;
}
};

//const int MAX_SIZE = 100;

class Queue {
private:
int* arr;
int front;
int rear;
int capacity;
int size;

public:
Queue(int capacity) {
this->capacity = capacity;
arr = new int[capacity];
front = 0;
rear = -1;
size = 0;
}

~Queue() {
delete[] arr;
}

void enqueue(int value) {


if (isFull()) {
cout << "Queue is full. Unable to enqueue." << endl;
return;
}

rear = (rear + 1) % capacity;


arr[rear] = value;
size++;
}

int dequeue() {
if (isEmpty()) {
cout << "Queue is empty. Unable to dequeue." << endl;
return -1;
}

int value = arr[front];


front = (front + 1) % capacity;
size--;
return value;
}

int frontValue() {
if (isEmpty()) {
cout << "Queue is empty. No front value." << endl;
return -1;
}

return arr[front];
}

bool isEmpty() {
return size == 0;
}

int count() {
return size;
}

void clear() {
front = 0;
rear = -1;
size = 0;
}

void display() {
if (isEmpty()) {
cout << "Queue is empty. Nothing to display." << endl;
return;
}

cout << "Queue: ";


int index = front;
for (int i = 0; i < size; i++) {
cout << arr[index] << " ";
index = (index + 1) % capacity;
}
cout << endl;
}
int peek() {
return frontValue();
}

bool isFull() {
return size == capacity;
}

void resize(int newSize) {


int* newArr = new int[newSize];
int index = front;
for (int i = 0; i < size; i++) {
newArr[i] = arr[index];
index = (index + 1) % capacity;
}

delete[] arr;
arr = newArr;
front = 0;
rear = size - 1;
capacity = newSize;
}
};

int main() {
int choice;
m:
cout << "\n\n\t\t\t-----------------------------------------\n\n";
cout << "\t\t\t\tEnter 1 for linked list" << endl;
cout << "\t\t\t\tEnter 2 for stack" << endl;
cout << "\t\t\t\tEnter 3 for double linked list" << endl;
cout << "\t\t\t\tEnter 4 for queue" << endl;
cout << "\t\t\t\tEnter your choice : ";
cin >> choice;
cout << "\n\n\t\t\t-----------------------------------------\n\n";
switch (choice) {
case 1: {
LinkedList list;
char ch;
int value, num;
c:
cout << "\n\t\t\t------------------------------------------\n";
cout << endl
<< endl;
cout << "\t\t\t\t1: Insert " << endl;
cout << "\t\t\t\t2: Remove " << endl;
cout << "\t\t\t\t3: Search " << endl;
cout << "\t\t\t\t4: Update " << endl;
cout << "\t\t\t\t5: Count " << endl;
cout << "\t\t\t\t6: Display " << endl;
cout << "\t\t\t\t7: Exit " << endl;
cout << "\t\t\t\tEnter your choice : ";
cin >> ch;
cout << "\n\t\t\t------------------------------------------\n";

switch (ch) {
case '1':

cout << "How many values do you want to insert: ";


cin >> num;
for (int i = 1; i <= num; i++) {
cout << endl
<< "Enter value to insert: ";
cin >> value;
list.insert(value);
}
goto c;
break;
case '2':
cout << endl
<< "Enter value to remove: ";
cin >> value;
list.remove(value);
goto c;
break;
case '3':
cout << endl
<< "Enter value to search: ";
cin >> value;
if (list.search(value))
cout << "Value found in the list.\n";
else
cout << "Value not found in the list.\n";
goto c;
break;
case '4':
int oldValue, newValue;
cout << endl
<< "Enter value to update: ";
cin >> oldValue;
cout << endl
<< "Enter new value: ";
cin >> newValue;
list.update(oldValue, newValue);
goto c;
break;
case '5':
cout << endl<< "Count: " << list.count() << endl;
goto c;
break;
case '6':
list.display();
cout << endl;
goto c;
break;
case '7':
break;
exit;
goto m;
default:
cout << "Invalid option. Please try again." << endl;
goto c;
break;
}

break;
}

case 2: {
Stack stack;
int choice, value,num;

do {
cout << "1: Push" << endl;
cout << "2: Pop" << endl;
cout << "3: Peek" << endl;
cout << "4: Search" << endl;
cout << "5: Update" << endl;
cout << "6: Display" << endl;
cout << "7: Exit" << endl;
cout << "Enter your choice: ";
cin >> choice;

switch (choice) {
case 1:
cout<<"Enter the number of values to push";
cin>>num;
for (int i=1; i<= num; i++)
{
cout << "Enter value to push: ";
cin >> value;
stack.push(value);
}
break;
case 2:
stack.pop();
break;
case 3:
cout << "Top of stack: " << stack.peek() << endl;
break;
case 4:
cout << "Enter value to search: ";
cin >> value;
stack.search(value);
break;
case 5:
int oldValue, newValue;
cout << "Enter value to update: ";
cin >> oldValue;
cout << "Enter new value: ";
cin >> newValue;
stack.update(oldValue, newValue);
break;
case 6:
stack.display();
break;
case 7:
cout << "Exiting..." << endl;
break;
default:
cout << "Invalid option. Please try again." << endl;
break;
}

cout << endl;


} while (choice != 7);

return 0;
}
case 3:
{
DoublyLinkedList list;
int choice, value,num;

do
{
cout << "Choose an option:" << endl;
cout << "1. Insert value" << endl;
cout << "2. Remove value" << endl;
cout << "3. Search value" << endl;
cout << "4. Update value" << endl;
cout << "5. Display list" << endl;
cout << "6. Reverse list" << endl;
cout << "7. Exit" << endl;
cout << "Enter your choice: ";
cin >> choice;

switch (choice) {
case 1:
cout<<"Enter the number of values to push";
cin>>num;
for (int i=1; i<= num; i++)
{
cout << "Enter value to insert: ";
cin >> value;
list.insert(value);
}
break;
case 2:
cout << "Enter value to remove: ";
cin >> value;
list.remove(value);
break;
case 3:
cout << "Enter value to search: ";
cin >> value;
list.search(value);
break;
case 4:
int oldValue, newValue;
cout << "Enter old value to update: ";
cin >> oldValue;
cout << "Enter new value: ";
cin >> newValue;
list.update(oldValue, newValue);
break;
case 5:
list.display();
break;
case 6:
list.reverse();
break;
case 7:
cout << "Exiting..." << endl;
break;
default:
cout << "Invalid option. Please try again." << endl;
break;
}

cout << endl;


} while (choice != 7);

return 0;
}
case 4: {
int capacity;
cout << "Enter the capacity of the queue: ";
cin >> capacity;

Queue queue(capacity);
char ch;
int choice, value;
while (true) {
cout << "\n---------------------------" << endl;
cout << "Queue Operations:" << endl;
cout << "1. Enqueue" << endl;
cout << "2. Dequeue" << endl;
cout << "3. Front Value" << endl;
cout << "4. Is Empty" << endl;
cout << "5. Count" << endl;
cout << "6. Clear" << endl;
cout << "7. Display" << endl;
cout << "8. Peek" << endl;
cout << "9. Is Full" << endl;
cout << "10. Resize" << endl;
cout << "0. Exit" << endl;
cout << "Enter your choice: ";
cin >> choice;
cout << "---------------------------" << endl;

switch (choice) {
case 0:
cout << "Exiting..." << endl;
return 0;
case 1:
cout << "Enter value to enqueue: ";
cin >> value;
queue.enqueue(value);
break;
case 2:
value = queue.dequeue();
if (value != -1)
cout << "Dequeued value: " << value << endl;
break;
case 3:
value = queue.frontValue();
if (value != -1)
cout << "Front value: " << value << endl;
break;
case 4:
cout << "Is empty? " << (queue.isEmpty() ? "Yes" : "No") << endl;
break;
case 5:
cout << "Count: " << queue.count() << endl;
break;
case 6:
queue.clear();
cout << "Queue cleared." << endl;
break;
case 7:
queue.display();
break;
case 8:
value = queue.peek();
if (value != -1)
cout << "Peek value: " << value << endl;
break;
case 9:
cout << "Is full? " << (queue.isFull() ? "Yes" : "No") << endl;
break;
case 10:
cout << "Enter new size: ";
cin >> value;
queue.resize(value);
cout << "Queue resized." << endl;
break;
default:
cout << "Invalid choice. Please try again." << endl;
break;
}
} while ( ch != 5);
break;
}

default:
cout << "Invalid choice. Please try again." << endl;
break;
}

cout << "\n\n\t\t\t-----------------------------------------\n\n";


return 0;
}

You might also like