0% found this document useful (0 votes)
22 views32 pages

My_Manual

The document is a lab manual for the Data Structures course (COMP2117) at the University of Education, Lahore, detailing various data structures and algorithms. It includes a list of experiments covering topics such as arrays, stacks, queues, and sorting algorithms, along with their definitions, key operations, and sample code implementations. The manual serves as a practical guide for students to understand and apply fundamental concepts in data structures.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
22 views32 pages

My_Manual

The document is a lab manual for the Data Structures course (COMP2117) at the University of Education, Lahore, detailing various data structures and algorithms. It includes a list of experiments covering topics such as arrays, stacks, queues, and sorting algorithms, along with their definitions, key operations, and sample code implementations. The manual serves as a practical guide for students to understand and apply fundamental concepts in data structures.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 32

1

Lab Manual
Data Structures
COMP2117

Course Name Data Structure


Course Code COMP2117
Credit Hours 4(3+3)
Program BSIT/ BSCS
Semester III

Submitted By
Name: Abdul Rehman

Roll#: bsf23003501

Department of Information Sciences,

University of Education, Lahore.


2

Data Structures & Analysis of Algorithms

List of Experiments
Lab
Lab Title Page
No.
Lab # 1 Array 3

Lab # 2 Stack 6

Lab # 3 Linear Search 9

Lab # 4 Binary Search 11

Lab # 5 Bubble Sort 13

Lab # 6 Selection Sort 14

Lab # 7 Insertion Sort 15

Lab # 8 Queue 17

Lab # 9 Circular Queue 19


Lab #
Single Linked List 23
13
Lab #
Double Linked List 28
14
Lab #
15
3

Array
An array is a fundamental data structure in programming and algorithms, designed to store
elements of the same type in contiguous memory locations. Arrays are extensively used due to
their simplicity and efficiency in accessing elements using indices. Below are essential array
operations and their implementations:
Basic Array Operations
1. Traversal
 Description: Access and process each element in the array sequentially.
 Time Complexity: O(n)O(n)O(n)
Code:

Input: Output:
#include <iostream> Enter the size of the array: 3
Enter 3 elements:
using namespace std; 123
int main() { The elements of the array are: 1 2 3

int n;
cout << "Enter the size of the array: ";
cin >> n;
int arr[n];
cout << "Enter " << n << " elements:" <<
endl;
for (int i = 0; i < n; i++) {
cin >> arr[i];
}
cout << "The elements of the array are: ";
for (int i = 0; i < n; i++) {
cout << arr[i] << " ";
}
cout << endl;
return 0;
4

2. Insertion
 Description: Add a new element at a specific position in the array.
 Time Complexity:
o O(1)O(1)O(1) for appending.
o O(n)O(n)O(n) for insertion at any other position (due to shifting elements).
Code:

Input: Output:
#include <iostream> Enter the size of the array: 3
Enter 3 elements: 1
using namespace std; 2
int main() { 3
Enter the position to insert the element: 2
int n, pos, value; Enter the value to insert: 4
Array after insertion: 1 2 4 3
cout << "Enter the size of the array: ";
cin >> n;
int arr[n + 1];
cout << "Enter " << n << " elements: ";
for (int i = 0; i < n; i++) {
cin >> arr[i];
}
cout << "Enter the position to insert the
element: ";
cin >> pos;
cout << "Enter the value to insert: ";
cin >> value;
for (int i = n; i > pos; i--) {
arr[i] = arr[i - 1];
5

}
arr[pos] = value;
n++;
cout << "Array after insertion: ";
for (int i = 0; i < n; i++) {
cout << arr[i] << " ";
}
cout << endl;
return 0;
}

3. Deletion
 Description: Remove an element from a specified position in the array.
 Time Complexity: O(n)O(n)O(n) (due to shifting elements).
Code:

Input: Output:
#include <iostream> Enter the size of the array: 3
Enter 3 elements: 1 2 3
using namespace std; Enter the position to delete the element: 0
int main() { Array after deletion: 2 3

int n, pos;
cout << "Enter the size of the array: ";
cin >> n;
int arr[n];
cout << "Enter " << n << " elements: ";
for (int i = 0; i < n; i++) {
cin >> arr[i];
6

}
cout << "Enter the position to delete the
element: ";
cin >> pos;
for (int i = pos; i < n - 1; i++) {
arr[i] = arr[i + 1];
}
n--;
cout << "Array after deletion: ";
for (int i = 0; i < n; i++) {
cout << arr[i] << " ";
}
cout << endl;
return 0;
}

Stack
A stack is a linear data structure that follows the LIFO (Last In, First Out) principle, meaning the
last element added is the first to be removed.
Key Operations
1. Push: Add an element to the top of the stack.
2. Pop: Remove and return the top element.
3. Peek/Top: View the top element without removing it.
4. isEmpty: Check if the stack is empty.
Code for Stack using Array

Input: Output:
#include <iostream> Top element: 30
Popped element: 30
7

using namespace std; Top element after pop: 20

class Stack {
int* arr;
int top;
int capacity;

public:
Stack(int size) {
arr = new int[size];
capacity = size;
top = -1;
}

void push(int value) {


if (top == capacity - 1) {
cout << "Stack Overflow" << endl;
return;
}
arr[++top] = value;
}

int pop() {
if (top == -1) {
cout << "Stack Underflow" << endl;
return -1;
}
8

return arr[top--];
}

int peek() {
if (top == -1) {
cout << "Stack is empty" << endl;
return -1;
}
return arr[top];
}

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

~Stack() {
delete[] arr;
}
};
int main() {
Stack stack(5);

stack.push(10);
stack.push(20);
stack.push(30);
cout << "Top element: " << stack.peek() <<
endl;
9

cout << "Popped element: " << stack.pop()


<< endl;
cout << "Top element after pop: " <<
stack.peek() << endl;
return 0;
}

Linear Search
 Definition: A simple search algorithm that checks every element in the list sequentially
until the desired element is found or the list ends.
 Characteristics:
o Does not require the array to be sorted.
o Suitable for small datasets.
o Time Complexity:
 Best Case: O(1) (if the element is at the beginning).
 Worst Case: O(n) (if the element is at the end or not present).

Code:

Input: Output:
#include <iostream> Element 45 found at index 2
using namespace std;

int linearSearch(int arr[], int n, int key) {


for (int i = 0; i < n; i++) {
if (arr[i] == key) {
return i; // Return the index where the
10

key is found
}
}
return -1; // Return -1 if the key is not
found
}

int main() {
int arr[] = {10, 23, 45, 70, 11, 15};
int n = sizeof(arr) / sizeof(arr[0]);
int key = 45;

int result = linearSearch(arr, n, key);

if (result != -1) {
cout << "Element " << key << " found at
index " << result << endl;
} else {
cout << "Element " << key << " not
found." << endl;
}
return 0;
}
11

Binary Search
 Definition: A highly efficient search algorithm that repeatedly divides the search interval
in half. Works only on sorted arrays.
 Characteristics:
o Requires the array to be sorted in ascending or descending order.
o Time Complexity:
 Best Case: O(1) (when the middle element is the target).
 Worst and Average Case: O(log n).
Code:

Input: Output:
#include <iostream> Element 10 found at index 3
using namespace std;

int binarySearch(int arr[], int left, int right, int


key) {
while (left <= right) {
int mid = left + (right - left) / 2;

// Check if the key is at mid


if (arr[mid] == key) {
return mid;
}

// If key is smaller, search the left half


if (arr[mid] > key) {
right = mid - 1;
}
// If key is larger, search the right half
12

else {
left = mid + 1;
}
}
return -1; // Return -1 if the key is not
found
}

int main() {
int arr[] = {2, 3, 4, 10, 40};
int n = sizeof(arr) / sizeof(arr[0]);
int key = 10;

int result = binarySearch(arr, 0, n - 1, key);

if (result != -1) {
cout << "Element " << key << " found at
index " << result << endl;
} else {
cout << "Element " << key << " not
found." << endl;
}
return 0;
}
13

Sorting Algorithms
1. Bubble Sort
 Description: Compare adjacent elements and swap them if they're out of order. Repeat
until the array is sorted.
 Time Complexity: O(n2)O(n^2)O(n2)
Code:

Input: Output:
#include <iostream> Enter the size of the array: 4
Enter 4 elements: 2 5 1 3
using namespace std; Sorted array: 1 2 3 5
int main() {
int n;
cout << "Enter the size of the array: ";
cin >> n;
int arr[n];
cout << "Enter " << n << " elements: ";
for (int i = 0; i < n; i++) {
cin >> arr[i];
}
for (int i = 0; i < n - 1; i++) {
for (int j = 0; j < n - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
swap(arr[j], arr[j + 1]);
}
}
}
cout << "Sorted array: ";
for (int i = 0; i < n; i++) {
cout << arr[i] << " ";
14

}
cout << endl;
return 0;
}

2. Selection Sort
 Divides the array into a sorted and an unsorted region.
 Repeatedly selects the smallest element from the unsorted region and moves it to the
sorted region.
 Time Complexity: O(n²).
Code:

Input: Output:
#include <iostream> Sorted array: 10 13 14 29 37
using namespace std;

void selectionSort(int arr[], int n) {


for (int i = 0; i < n - 1; i++) {
int minIndex = i;
for (int j = i + 1; j < n; j++) {
if (arr[j] < arr[minIndex])
minIndex = j;
}
// Swap arr[i] and arr[minIndex]
int temp = arr[minIndex];
arr[minIndex] = arr[i];
arr[i] = temp;
}
15

void displayArray(int arr[], int n) {


for (int i = 0; i < n; i++) {
cout << arr[i] << " ";
}
cout << endl;
}

int main() {
int arr[] = {29, 10, 14, 37, 13};
int n = sizeof(arr) / sizeof(arr[0]);
selectionSort(arr, n);
cout << "Sorted array: ";
displayArray(arr, n);
return 0;
}

3. Insertion Sort
 Builds the sorted list one element at a time by comparing the current element to the
already sorted portion.
 Time Complexity: O(n²) for the worst case, O(n) for nearly sorted arrays.
Code:

Input: Output:
#include <iostream> Sorted array: 5 6 11 12 13
using namespace std;
16

void insertionSort(int arr[], int n) {


for (int i = 1; i < n; i++) {
int key = arr[i];
int j = i - 1;

while (j >= 0 && arr[j] > key) {


arr[j + 1] = arr[j];
j--;
}
arr[j + 1] = key;
}
}

void displayArray(int arr[], int n) {


for (int i = 0; i < n; i++) {
cout << arr[i] << " ";
}
cout << endl;
}

int main() {
int arr[] = {12, 11, 13, 5, 6};
int n = sizeof(arr) / sizeof(arr[0]);
insertionSort(arr, n);
cout << "Sorted array: ";
displayArray(arr, n);
return 0;
17

Queue
A queue is a linear data structure that follows the FIFO (First In, First Out) principle, meaning
the first element added is the first to be removed.
Key Operations
1. Enqueue: Add an element to the rear of the queue.
2. Dequeue: Remove and return the front element.
3. Peek/Front: View the front element without removing it.
4. isEmpty: Check if the queue is empty.
Code for Queue using Array

Input: Output:
#include <iostream> Front element: 10
Front element after dequeue: 20
using namespace std;

class Queue {
int* arr;
int front, rear, capacity;

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

void enqueue(int value) {


18

if (rear == capacity - 1) {
cout << "Queue Overflow" << endl;
return;
}
if (front == -1) front = 0;
arr[++rear] = value;
}

int dequeue() {
if (front == -1 || front > rear) {
cout << "Queue Underflow" << endl;
return -1;
}
return arr[front++];
}

int peek() {
if (front == -1 || front > rear) {
cout << "Queue is empty" << endl;
return -1;
}
return arr[front];
}

bool isEmpty() {
return front == -1 || front > rear;
}
19

~Queue() {
delete[] arr;
}
};

int main() {
Queue queue(5);

queue.enqueue(10);
queue.enqueue(20);
queue.enqueue(30);
cout << "Front element: " << queue.peek()
<< endl;

queue.dequeue();
cout << "Front element after dequeue: " <<
queue.peek() << endl;

return 0;
}

Circular Queue
A circular queue is an advanced version of a linear queue where the last position connects back
to the first. This connection makes it efficient in utilizing memory and handling operations
seamlessly in fixed-sized storage.
Key Characteristics of Circular Queue
1. Circular Connection:
20

o The rear wraps around to the front when it reaches the end, enabling continuous
usage of space.
2. Efficient Memory Utilization:
o It avoids leaving unused spaces in the queue after dequeuing.
3. Index Management:
o Positions are handled using modular arithmetic:
 rear = (rear + 1) % size
 front = (front + 1) % size
Basic Operations
 Enqueue: Add an element to the rear of the queue.
 Dequeue: Remove an element from the front.
 Peek/Front: Retrieve the element at the front without removing it.
 isEmpty: Check if the queue is empty.
 isFull: Check if the queue is full.
Code for Circular Queue

Input: Output:
#include <iostream> Front element: 10
Front element after dequeue: 20
using namespace std; Is queue full: Yes
class CircularQueue { Dequeue: 20
Dequeue: 30
int *arr; Dequeue: 40
Dequeue: 50
int front, rear, size, capacity;
Dequeue: 60
public: Is queue empty: Yes

CircularQueue(int cap) {
capacity = cap;
arr = new int[capacity];
front = -1;
rear = -1;
21

size = 0;
}
bool isEmpty() {
return size == 0;
}
bool isFull() {
return size == capacity;
}
void enqueue(int value) {
if (isFull()) {
cout << "Queue Overflow" << endl;
return;
}
if (front == -1) front = 0;
rear = (rear + 1) % capacity;
arr[rear] = value;
size++;
}
int dequeue() {
if (isEmpty()) {
cout << "Queue Underflow" << endl;
return -1;
}
int result = arr[front];
front = (front + 1) % capacity;
size--;
return result;
22

}
int peek() {
if (isEmpty()) {
cout << "Queue is empty" << endl;
return -1;
}
return arr[front];
}
~CircularQueue() {
delete[] arr;
}
};
int main() {
CircularQueue cq(5);
cq.enqueue(10);
cq.enqueue(20);
cq.enqueue(30);
cout << "Front element: " << cq.peek() <<
endl;
cq.dequeue();
cout << "Front element after dequeue: " <<
cq.peek() << endl;
cq.enqueue(40);
cq.enqueue(50);
cq.enqueue(60);
cout << "Is queue full: " << (cq.isFull() ?
"Yes" : "No") << endl;
while (!cq.isEmpty())
23

cout << "Dequeue: " << cq.dequeue() <<


endl;
cout << "Is queue empty: " << (cq.isEmpty()
? "Yes" : "No") << endl;
return 0;
}

Singly Linked List (SLL)


Characteristics:
 Linear data structure made up of nodes.
 Each node contains:
o Data: Stores the actual data.
o Pointer: Points to the next node in the list.
 The last node points to NULL, signifying the end of the list.
 Dynamic memory allocation, no fixed size.

Operations:
1. Insertion:
o At the beginning.
o At the end.
o At a specific position.
2. Deletion:
o From the beginning.
o From the end.
o A specific node by key.
3. Traversal:
o Traverse the list to print elements or perform operations on them.
Code:

Input: Output:
10 -> 20 -> 30 -> NULL
24

#include <iostream> 10 -> 30 -> NULL


using namespace std;

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

// Function to insert a node at the beginning


void insertAtBeginning(Node*& head, int
value) {
Node* newNode = new Node();
newNode->data = value;
newNode->next = head;
head = newNode;
}

// Function to insert a node at the end


void insertAtEnd(Node*& head, int value) {
Node* newNode = new Node();
newNode->data = value;
newNode->next = NULL;

if (head == NULL) {
head = newNode;
return;
25

Node* temp = head;


while (temp->next != NULL) {
temp = temp->next;
}
temp->next = newNode;
}

// Function to delete a node by key


void deleteNode(Node*& head, int key) {
Node* temp = head;
Node* prev = NULL;

if (temp != NULL && temp->data == key) {


head = temp->next;
delete temp;
return;
}

while (temp != NULL && temp->data !=


key) {
prev = temp;
temp = temp->next;
}

if (temp == NULL) return;


26

prev->next = temp->next;
delete temp;
}

// Function to display the linked list


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

// Main function to test the SLL


int main() {
Node* head = NULL;

insertAtBeginning(head, 10);
insertAtEnd(head, 20);
insertAtEnd(head, 30);
displayList(head);

deleteNode(head, 20);
displayList(head);
27

return 0;
}

Sorting Techniques
1. Bubble Sort
 Simple sorting algorithm that repeatedly steps through the list, compares adjacent
elements, and swaps them if they are in the wrong order.
 Time Complexity: O(n²) for worst and average cases.
Code Implementation:
cpp
Copy code
#include <iostream>
using namespace std;

void bubbleSort(int arr[], int n) {


for (int i = 0; i < n - 1; i++) {
for (int j = 0; j < n - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
// Swap arr[j] and arr[j+1]
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
28

void displayArray(int arr[], int n) {


for (int i = 0; i < n; i++) {
cout << arr[i] << " ";
}
cout << endl;
}

int main() {
int arr[] = {64, 34, 25, 12, 22, 11, 90};
int n = sizeof(arr) / sizeof(arr[0]);
bubbleSort(arr, n);
cout << "Sorted array: ";
displayArray(arr, n);
return 0;
}

Doubly Linked List (DLL)


A doubly linked list is a type of linked list in which each node contains two pointers:
1. Next pointer: Points to the next node in the sequence.
2. Previous pointer: Points to the previous node.
Characteristics of DLL
 Nodes are connected in both directions.
 Traversal is possible in forward and backward directions.
 Allows more flexibility compared to singly linked lists, but uses more memory due to the
additional pointer.
Structure of a Node in DLL
struct Node {
29

int data;
Node* next;
Node* prev;

Node(int value) {
data = value;
next = nullptr;
prev = nullptr;
}
};
Operations on Doubly Linked List
1. Insertion
o At the beginning, end, or any given position.
2. Deletion
o From the beginning, end, or a specific position.
3. Traversal
o Forward and backward.
Code for DLL

Input: Output:
#include <iostream> 10 20 30
30 20 10
using namespace std; 10 20

struct Node {
int data;
Node* next;
Node* prev;
30

Node(int value) {
data = value;
next = nullptr;
prev = nullptr;
}
};

class DoublyLinkedList {
Node* head;

public:
DoublyLinkedList() {
head = nullptr;
}

void insertAtEnd(int value) {


Node* newNode = new Node(value);
if (!head) {
head = newNode;
return;
}
Node* temp = head;
while (temp->next)
temp = temp->next;
temp->next = newNode;
newNode->prev = temp;
}
31

void deleteAtEnd() {
if (!head) {
cout << "List is empty" << endl;
return;
}
if (!head->next) {
delete head;
head = nullptr;
return;
}
Node* temp = head;
while (temp->next)
temp = temp->next;
temp->prev->next = nullptr;
delete temp;
}
void displayForward() {
Node* temp = head;
while (temp) {
cout << temp->data << " ";
temp = temp->next;
}
cout << endl;
}
void displayBackward() {
if (!head) return;
32

Node* temp = head;


while (temp->next)
temp = temp->next;
while (temp) {
cout << temp->data << " ";
temp = temp->prev;
}
cout << endl;
}
};
int main() {
DoublyLinkedList dll;
dll.insertAtEnd(10);
dll.insertAtEnd(20);
dll.insertAtEnd(30);
dll.displayForward();
dll.displayBackward();
dll.deleteAtEnd();
dll.displayForward();
return 0;
}

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy