Data Structures Practical Using C++
220C31
1. Array implementation of stacks
#include <iostream.h>
#include <conio.h>
class Stack
{
private:
int top;
int capacity;
int* array;
public:
Stack(int size)
{
capacity = size;
array = new int[capacity];
top = -1;
}
~Stack()
{
delete[] array;
}
void push(int element)
{
if (isFull())
{
cout << "Stack overflow. Unable to push " << element << endl;
return;
}
array[++top] = element;
}
int pop()
{
if (isEmpty())
{
cout << "Stack underflow. Unable to pop" << endl;
return -1;
}
return array[top--];
}
int peek()
{
if (isEmpty())
{
cout << "Stack is empty" << endl;
return -1;
}
return array[top];
}
int isEmpty()
{
return top == -1;
}
int isFull()
{
return top == capacity - 1;
}
void printStack()
{
if (isEmpty())
{
cout << "Stack is empty" << endl;
return;
}
cout << "Stack elements: ";
for (int i = 0; i <= top; i++)
{
cout << array[i] << " ";
}
cout << endl;
}
};
int main()
{
clrscr();
Stack stack(5);
stack.push(10);
stack.push(20);
stack.push(30);
stack.push(40);
stack.push(50);
stack.push(60);
stack.printStack();
cout << "Top element is: " << stack.peek() << endl;
cout << "Popped element is: " << stack.pop() << endl;
cout << "Popped element is: " << stack.pop() << endl;
stack.printStack();
getch();
return 0;
}
OUTPUT
Stack overflow. Unable to push 60
Stack elements: 10 20 30 40 50
Top element is: 50
Popped element is: 50
Popped element is: 40
Stack elements: 10 20 30
2. Array implementation of Queues
#include <iostream.h>
#include <conio.h>
class Queue
{
private:
int front, rear, size;
int capacity;
int* array;
public:
Queue(int cap)
{
capacity = cap;
front = size = 0;
rear = capacity - 1;
array = new int[capacity];
}
~Queue()
{
delete[] array;
}
void enqueue(int item)
{
if (isFull())
{
cout << "Queue overflow. Unable to enqueue " << item << endl;
return;
}
rear = (rear + 1) % capacity;
array[rear] = item;
size++;
cout << item << " enqueued to queue" << endl;
}
int dequeue()
{
if (isEmpty())
{
cout << "Queue underflow. Unable to dequeue" << endl;
return -1;
}
int item = array[front];
front = (front + 1) % capacity;
size--;
return item;
}
int frontItem()
{
if (isEmpty())
{
cout << "Queue is empty" << endl;
return -1;
}
return array[front];
}
int rearItem()
{
if (isEmpty())
{
cout << "Queue is empty" << endl;
return -1;
}
return array[rear];
}
int isEmpty()
{
return (size == 0);
}
int isFull()
{
return (size == capacity);
}
void printQueue() {
if (isEmpty()) {
cout << "Queue is empty" << endl;
return;
}
cout << "Queue elements: ";
for (int i = 0; i < size; i++)
{
cout << array[(front + i) % capacity] << " ";
}
cout << endl;
}
};
int main()
{
clrscr();
Queue queue(5);
queue.enqueue(10);
queue.enqueue(20);
queue.enqueue(30);
queue.enqueue(40);
queue.enqueue(50);
queue.enqueue(60);
queue.printQueue();
cout << "Front item is: " << queue.frontItem() << endl;
cout << "Rear item is: " << queue.rearItem() << endl;
cout << "Dequeued element is: " << queue.dequeue() << endl;
cout << "Dequeued element is: " << queue.dequeue() << endl;
queue.printQueue();
getch();
return 0;
}
OUTPUT
10 enqueued to queue
20 enqueued to queue
30 enqueued to queue
40 enqueued to queue
50 enqueued to queue
Queue overflow. Unable to enqueue 60
Queue elements: 10 20 30 40 50
Front item is: 10
Rear item is: 50
Dequeued element is: 10
Dequeued element is: 20
Queue elements: 30 40 50
3. Linked list implementation of stacks
#include <iostream.h>
#include <conio.h>
class Node
{
public:
int data;
Node* next;
Node(int value)
{
data = value;
next = NULL;
}
};
class Stack
{
private:
Node* top;
public:
Stack()
{
top = NULL;
}
~Stack()
{
while (!isEmpty())
{
pop();
}
}
int isEmpty()
{
return top == NULL;
}
void push(int value)
{
Node* newNode = new Node(value);
newNode->next = top;
top = newNode;
cout << value << " pushed to stack.\n";
}
int pop()
{
if (isEmpty())
{
cout << "Stack underflow! Cannot pop from empty stack.\n";
return -1;
}
int poppedValue = top->data;
Node* temp = top;
top = top->next;
delete temp;
return poppedValue;
}
int peek()
{
if (isEmpty())
{
cout << "Stack is empty.\n";
return -1;
}
return top->data;
}
};
int main()
{
clrscr();
Stack stack;
stack.push(10);
stack.push(20);
stack.push(30);
cout << stack.pop() << " popped from stack.\n";
cout << "Top element is: " << stack.peek() << endl;
getch();
return 0;
}
OUTPUT:
10 pushed to stack.
20 pushed to stack.
30 pushed to stack.
30 popped from stack.
Top element is: 20
4. Linked list implementation of Queues
#include <iostream.h>
#include <conio.h>
struct Node
{
int data;
Node* next;
};
class Queue
{
private:
Node* front;
Node* rear;
public:
Queue()
{
front = NULL;
rear = NULL;
}
~Queue()
{
while (front != NULL)
{
Node* temp = front;
front = front->next;
delete temp;
}
}
void enqueue(int value)
{
Node* newNode = new Node();
newNode->data = value;
newNode->next = NULL;
if (rear == NULL)
{
front = rear = newNode;
return;
}
rear->next = newNode;
rear = newNode;
}
void dequeue()
{
if (front == NULL)
{
cout << "Queue is empty" << endl;
return;
}
Node* temp = front;
front = front->next;
if (front == NULL)
{
rear = NULL;
}
delete temp;
}
void display()
{
if (front == NULL)
{
cout << "Queue is empty" << endl;
return;
}
Node* temp = front;
while (temp != NULL)
{
cout << temp->data << " ";
temp = temp->next;
}
cout << endl;
}
};
int main()
{
clrscr();
Queue q;
q.enqueue(10);
q.enqueue(20);
q.enqueue(30);
cout << "Queue after enqueue operations: ";
q.display();
q.dequeue();
cout << "Queue after one dequeue operation: ";
q.display();
q.dequeue();
q.dequeue();
cout << "Queue after two more dequeue operations: ";
q.display();
q.dequeue();
getch();
return 0;
}
OUTPUT:
Queue after enqueue operations: 10 20 30
Queue after one dequeue operation: 20 30
Queue after two more dequeue operations: Queue is empty
Queue is empty
5. Covert infix expression to postfix.
#include <iostream.h>
#include <conio.h>
#include <stdlib.h>
#include <ctype.h>
#define MAX 100
class Stack
{
int top;
char items[MAX];
public:
Stack()
{
top = -1;
}
void push(char item)
{
if (top >= (MAX - 1))
{
cout << "Stack Overflow \n";
} else {
items[++top] = item;
}
}
char pop()
{
if (top < 0)
{
cout << "Stack Underflow \n";
return 0;
} else {
return items[top--];
}
}
char peek()
{
if (top < 0)
{
cout << "Stack is Empty\n";
return 0;
} else {
return items[top];
}
}
int isEmpty()
{
return (top < 0);
}
};
int precedence(char op)
{
switch (op)
{
case '+':
case '-':
return 1;
case '*':
case '/':
return 2;
case '^':
return 3;
}
return 0;
}
int isOperator(char ch)
{
return (ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '^');
}
void infixToPostfix(char* infix, char* postfix)
{
Stack stack;
int i = 0, k = 0;
while (infix[i] != '\0')
{
if (isalnum(infix[i]))
{
postfix[k++] = infix[i];
} else if (infix[i] == '(')
{
stack.push(infix[i]);
} else if (infix[i] == ')')
{
while (!stack.isEmpty() && stack.peek() != '(')
{
postfix[k++] = stack.pop();
}
if (!stack.isEmpty() && stack.peek() != '(')
{
cout << "Invalid expression\n";
return;
} else {
stack.pop(); // Pop '('
}
} else if (isOperator(infix[i]))
{
while (!stack.isEmpty() && precedence(stack.peek()) >= precedence(infix[i]))
{
postfix[k++] = stack.pop();
}
stack.push(infix[i]);
}
i++;
}
while (!stack.isEmpty())
{
postfix[k++] = stack.pop();
}
postfix[k] = '\0';
}
void main()
{
clrscr();
char infix[MAX], postfix[MAX];
cout << "Enter an infix expression: ";
cin >> infix;
infixToPostfix(infix, postfix);
cout << "Postfix expression: " << postfix << endl;
getch();
}
OUTPUT:
Enter an infix expression: A+B*(C^D-E)
Postfix expression: ABCD^E- *+
6. Binary Tree Traversals (Inorder, Preorder, Postorder)
#include <iostream.h>
#include <conio.h>
struct Node
{
int data;
Node* left;
Node* right;
Node(int val) : data(val), left(NULL), right(NULL) {}
};
void inorder(Node* root)
{
if (root == NULL) return;
inorder(root->left);
cout << root->data << " ";
inorder(root->right);
}
void preorder(Node* root)
{
if (root == NULL) return;
cout << root->data << " ";
preorder(root->left);
preorder(root->right);
}
void postorder(Node* root)
{
if (root == NULL) return;
postorder(root->left);
postorder(root->right);
cout << root->data << " ";
}
Node* createNode(int data)
{
Node* newNode = new Node(data);
return newNode;
}
void main()
{
clrscr();
Node* root = createNode(1);
root->left = createNode(2);
root->right = createNode(3);
root->left->left = createNode(4);
root->left->right = createNode(5);
root->right->left = createNode(6);
root->right->right = createNode(7);
cout << "Inorder traversal: ";
inorder(root);
cout << endl;
cout << "Preorder traversal: ";
preorder(root);
cout << endl;
cout << "Postorder traversal: ";
postorder(root);
cout << endl;
getch();
}
OUTPUT
Inorder traversal: 4 2 5 1 6 3 7
Preorder traversal: 1 2 4 5 3 6 7
Postorder traversal: 4 5 2 6 7 3 1
7. Implementation of Linear search and binary search
#include <iostream.h>
#include <conio.h>
void bubbleSort(int arr[], int size)
{
for (int i = 0; i < size - 1; i++)
{
for (int j = 0; j < size - i - 1; j++)
{
if (arr[j] > arr[j + 1])
{
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
int linearSearch(int arr[], int size, int target)
{
for (int i = 0; i < size; i++)
{
if (arr[i] == target)
{
return i;
}
}
return -1;
}
int binarySearch(int arr[], int left, int right, int target)
{
while (left <= right)
{
int mid = left + (right - left) / 2;
if (arr[mid] == target)
{
return mid;
}
if (arr[mid] < target)
{
left = mid + 1;
} else
{
right = mid - 1;
}
}
return -1;
}
int main()
{
clrscr();
int size, target, choice;
cout << "Enter the number of elements in the array: ";
cin >> size;
int arr[100];
cout << "Enter the elements of the array: ";
for (int i = 0; i < size; i++)
{
cin >> arr[i];
}
cout << "Enter the target value to search: ";
cin >> target;
cout << "Choose the search method:\n";
cout << "1. Linear Search\n";
cout << "2. Binary Search\n";
cin >> choice;
int result;
switch(choice)
{
case 1:
result = linearSearch(arr, size, target);
break;
case 2:
bubbleSort(arr, size);
result = binarySearch(arr, 0, size - 1, target);
break;
default:
cout << "Invalid choice." << endl;
return 1;
}
if (result != -1)
{
cout << "Element found at index " << result << endl;
} else {
cout << "Element not found" << endl;
}
getch();
return 0;
}
OUTPUT 1:
Enter the number of elements in the array: 5
Enter the elements of the array: 2 6 1 7 3
Enter the target value to search: 7
Choos the search method:
1. Linear Search
2. Binary Search
1
Element found at index 3
OUTPUT 2:
Enter the number of elements in the array: 5
Enter the elements of the array: 2 6 1 7 3
Enter the target value to search: 7
Choos the search method:
1. Linear Search
2. Binary Search
2
Element found at index 4
8. Implementation of Depth-First Search & Breadth-First Search of Graphs.
#include <iostream.h>
#include <conio.h>
#include <stdlib.h>
#define MAX 10
class Graph
{
int adj[MAX][MAX];
int n;
public:
Graph(int nodes)
{
n = nodes;
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
adj[i][j] = 0;
}
void addEdge(int start, int end)
{
adj[start][end] = 1;
adj[end][start] = 1;
}
void DFS(int start);
void BFS(int start);
};
class Queue
{
int items[MAX];
int front, rear;
public:
Queue()
{
front = -1;
rear = -1;
}
int isEmpty()
{
return front == -1;
}
int isFull()
{
return (rear + 1) % MAX == front;
}
void enqueue(int element)
{
if (isFull())
{
cout << "Queue is full\n";
return;
}
if (isEmpty())
{
front = 0;
}
rear = (rear + 1) % MAX;
items[rear] = element;
}
int dequeue()
{
if (isEmpty())
{
cout << "Queue is empty\n";
return -1;
}
int element = items[front];
if (front == rear)
{
front = rear = -1;
} else {
front = (front + 1) % MAX;
}
return element;
}
};
void Graph::DFS(int start)
{
int visited[MAX] = {0};
int stack[MAX];
int top = -1;
stack[++top] = start;
cout << "DFS traversal: ";
while (top != -1)
{
start = stack[top--];
if (!visited[start])
{
cout << start << " ";
visited[start] = 1;
}
for (int i = n - 1; i >= 0; i--)
{
if (adj[start][i] && !visited[i])
stack[++top] = i;
}
}
cout << endl;
}
void Graph::BFS(int start)
{
int visited[MAX] = {0};
Queue q;
q.enqueue(start);
visited[start] = 1;
cout << "BFS traversal: ";
while (!q.isEmpty())
{
start = q.dequeue();
cout << start << " ";
for (int i = 0; i < n; i++)
{
if (adj[start][i] && !visited[i])
{
q.enqueue(i);
visited[i] = 1;
}
}
}
cout << endl;
}
void main()
{
clrscr();
int nodes, edges, start, end, choice;
cout << "Enter the number of nodes: ";
cin >> nodes;
Graph g(nodes);
cout << "Enter the number of edges: ";
cin >> edges;
for (int i = 0; i < edges; i++)
{
cout << "Enter edge (start end): ";
cin >> start >> end;
g.addEdge(start, end);
}
cout << "Enter the starting node for traversal: ";
cin >> start;
cout << "Choose the traversal method:\n";
cout << "1. Depth-First Search (DFS)\n";
cout << "2. Breadth-First Search (BFS)\n";
cin >> choice;
switch (choice)
{
case 1:
g.DFS(start);
break;
case 2:
g.BFS(start);
break;
default:
cout << "Invalid choice!";
}
getch();
}
Output 1:
Enter the number of nodes: 5
Enter the number of edges: 6
Enter edge (start end): 0 1
Enter edge (start end): 0 2
Enter edge (start end): 1 3
Enter edge (start end): 1 4
Enter edge (start end): 2 4
Enter edge (start end): 3 4
Enter the starting node for traversal: 0
Choose the traversal method:
1. Depth-First Search (DFS)
2. Breadth-First Search (BFS)
1
DFS traversal: 0 2 4 3 1
01342
Output 2:
Enter the number of nodes: 5
Enter the number of edges: 6
Enter edge (start end): 0 1
Enter edge (start end): 0 2
Enter edge (start end): 1 3
Enter edge (start end): 1 4
Enter edge (start end): 2 4
Enter edge (start end): 3 4
Enter the starting node for traversal: 0
Choose the traversal method:
1. Depth-First Search (DFS)
2. Breadth-First Search (BFS)
2
BFS traversal: 0 1 2 3 4
9. Finding single source shortest path of a Graph.
#include <iostream.h>
#include <conio.h>
#include <limits.h>
#define V 6
#define INF INT_MAX
int miniDist(int distance[], int Tset[])
{
int minimum = INF, ind;
for (int k = 0; k < V; k++)
{
if (Tset[k] == 0 && distance[k] <= minimum)
{
minimum = distance[k];
ind = k;
}
}
return ind;
}
void DijkstraAlgorithm(int graph[V][V], int src)
{
int distance[V];
int Tset[V];
for (int k = 0; k < V; k++)
{
distance[k] = INF;
Tset[k] = 0;
}
distance[src] = 0;
for (int count = 0; count < V - 1; count++)
{
int m = miniDist(distance, Tset);
Tset[m] = 1;
for (k = 0; k < V; k++)
{
if (!Tset[k] && graph[m][k] && distance[m] != INF && distance[m] + graph[m]
[k] < distance[k])
distance[k] = distance[m] + graph[m][k];
}
}
cout << "Vertex\t\tDistance from source vertex" << endl;
for (k = 0; k < V; k++)
{
char str = 65 + k;
cout << str << "\t\t\t" << distance[k] << endl;
}
}
int main()
{
clrscr();
int graph[V][V] = {
{0, 1, 2, 0, 0, 0},
{1, 0, 0, 5, 1, 0},
{2, 0, 0, 2, 3, 0},
{0, 5, 2, 0, 2, 2},
{0, 1, 3, 2, 0, 1},
{0, 0, 0, 2, 1, 0}};
DijkstraAlgorithm(graph, 0);
getch();
return 0;
}
Output:
Vertex Distance from source vertex
A 0
B 1
C 2
D 4
E 2
F 3