0% found this document useful (0 votes)
21 views

Data Structures With

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)
21 views

Data Structures With

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/ 14

DATA STRUCTURES WITH

C++ ASSIGNMENT-4

24/10/2024

ABHISHEK S K
ECE-01
B220634EC

1. Realize all the operations on stacks and queues using


a) Arrays
b) linked lists

A.
#include <iostream>
using namespace std;

class ArrayStack {
int *arr, cap, topIdx;
public:
ArrayStack(int size) : cap(size), topIdx(-1) { arr = new int[cap]; }
bool push(int elem) { if (topIdx == cap - 1) return false; arr[++topIdx] = elem; return true; }
bool pop() { if (topIdx == -1) return false; --topIdx; return true; }
int top() { return topIdx == -1 ? -1 : arr[topIdx]; }
bool isEmpty() { return topIdx == -1; }
};

class ArrayQueue {
int *arr, cap, frontIdx, rearIdx, size;
public:
ArrayQueue(int size) : cap(size), frontIdx(0), rearIdx(cap - 1), size(0) { arr = new int[cap]; }
bool enqueue(int elem) { if (size == cap) return false; rearIdx = (rearIdx + 1) % cap;
arr[rearIdx] = elem; ++size; return true; }
bool dequeue() { if (size == 0) return false; frontIdx = (frontIdx + 1) % cap; --size; return
true; }
int front() { return size == 0 ? -1 : arr[frontIdx]; }
bool isEmpty() { return size == 0; }
};

int main() {
ArrayStack stack(5);
ArrayQueue queue(5);
stack.push(10); queue.enqueue(20);
cout << "Stack Top: " << stack.top() << endl;
cout << "Queue Front: " << queue.front() << endl;
return 0;
}

B.
#include <iostream>
using namespace std;
struct NodeStack {
int data;
NodeStack *next;
NodeStack(int val) : data(val), next(nullptr) {}
};

class LinkedStack {
NodeStack *topNode;
public:
LinkedStack() : topNode(nullptr) {}
bool push(int elem) { NodeStack *n = new NodeStack(elem); n->next = topNode; topNode = n; return
true; }
bool pop() { if (!topNode) return false; NodeStack *tmp = topNode; topNode = topNode->next;
delete tmp; return true; }
int top() { return topNode ? topNode->data : -1; }
};

struct NodeQueue {
int data;
NodeQueue *next;
NodeQueue(int val) : data(val), next(nullptr) {}
};

class LinkedQueue {
NodeQueue *frontNode, *rearNode;
public:
LinkedQueue() : frontNode(nullptr), rearNode(nullptr) {}
bool enqueue(int elem) { NodeQueue *n = new NodeQueue(elem); if (!rearNode) frontNode = rearNode
= n; else { rearNode->next = n; rearNode = n; } return true; }
bool dequeue() { if (!frontNode) return false; NodeQueue *tmp = frontNode; frontNode =
frontNode->next; if (!frontNode) rearNode = nullptr; delete tmp; return true; }
int front() { return frontNode ? frontNode->data : -1; }
};

int main() {
LinkedStack stack;
LinkedQueue queue;
stack.push(15); queue.enqueue(25);
cout << "Linked Stack Top: " << stack.top() << endl;
cout << "Linked Queue Front: " << queue.front() << endl;
return 0;
}

2. Realize the following operations of a singly linked list. Output the results for each operation.
a. Insert Node at beginning
b. Insert node at last
c. Insert node at position
d. Sort Linked List
e. Delete a Particular Node
f. Update Node Value
g. Search Element
h. Display Linked List
i. Reverse Linked List

#include <iostream>
#include <stdexcept>

class LinkedList {
private:
struct Node {
int data;
Node* next;
explicit Node(int value) : data(value), next(nullptr) {}
};

Node* head;
int size;

// Helper method to get node at position


Node* getNodeAt(int position) const {
if (position < 0 || position >= size) {
throw std::out_of_range("Invalid position");
}

Node* current = head;


for (int i = 0; i < position; i++) {
current = current->next;
}
return current;
}

public:
LinkedList() : head(nullptr), size(0) {}

// Destructor to clean up memory


~LinkedList() {
Node* current = head;
while (current != nullptr) {
Node* next = current->next;
delete current;
current = next;
}
}

// a. Insert node at beginning


void insertAtBeginning(int value) {
Node* newNode = new Node(value);
newNode->next = head;
head = newNode;
size++;
}
// b. Insert node at last
void insertAtLast(int value) {
if (head == nullptr) {
insertAtBeginning(value);
return;
}

Node* current = head;


while (current->next != nullptr) {
current = current->next;
}

current->next = new Node(value);


size++;
}

// c. Insert node at position


void insertAtPosition(int value, int position) {
if (position < 0 || position > size) {
throw std::out_of_range("Invalid position");
}

if (position == 0) {
insertAtBeginning(value);
return;
}

Node* previous = getNodeAt(position - 1);


Node* newNode = new Node(value);
newNode->next = previous->next;
previous->next = newNode;
size++;
}

// d. Sort Linked List (using bubble sort)


void sort() {
if (size <= 1) return;

bool swapped;
do {
swapped = false;
Node* current = head;
Node* previous = nullptr;

while (current->next != nullptr) {


if (current->data > current->next->data) {
// Swap nodes
Node* temp = current->next;
current->next = temp->next;
temp->next = current;

if (previous == nullptr) {
head = temp;
} else {
previous->next = temp;
}
previous = temp;
swapped = true;
} else {
previous = current;
current = current->next;
}
}
} while (swapped);
}

// e. Delete a Particular Node


void deleteNode(int value) {
if (head == nullptr) {
throw std::runtime_error("List is empty");
}

if (head->data == value) {
Node* temp = head;
head = head->next;
delete temp;
size--;
return;
}

Node* current = head;


while (current->next != nullptr && current->next->data != value) {
current = current->next;
}

if (current->next == nullptr) {
throw std::runtime_error("Value not found");
}

Node* temp = current->next;


current->next = temp->next;
delete temp;
size--;
}

// f. Update Node Value


void updateNode(int oldValue, int newValue) {
Node* current = head;
bool found = false;

while (current != nullptr) {


if (current->data == oldValue) {
current->data = newValue;
found = true;
break;
}
current = current->next;
}

if (!found) {
throw std::runtime_error("Value not found");
}
}
// g. Search Element
bool search(int value) const {
Node* current = head;
while (current != nullptr) {
if (current->data == value) {
return true;
}
current = current->next;
}
return false;
}

// Find position of element


int findPosition(int value) const {
Node* current = head;
int position = 0;

while (current != nullptr) {


if (current->data == value) {
return position;
}
current = current->next;
position++;
}

return -1;
}

// h. Display Linked List


void display() const {
if (head == nullptr) {
std::cout << "List is empty" << std::endl;
return;
}

Node* current = head;


while (current != nullptr) {
std::cout << current->data;
if (current->next != nullptr) {
std::cout << " -> ";
}
current = current->next;
}
std::cout << std::endl;
}

// i. Reverse Linked List


void reverse() {
Node *prev = nullptr, *current = head, *next = nullptr;

while (current != nullptr) {


next = current->next;
current->next = prev;
prev = current;
current = next;
}
head = prev;
}

// Additional utility methods


bool isEmpty() const {
return head == nullptr;
}

int getSize() const {


return size;
}
};

int main() {
try {
LinkedList list;

// Test insertions
std::cout << "Inserting elements..." << std::endl;
list.insertAtBeginning(3);
list.insertAtLast(7);
list.insertAtBeginning(1);
list.insertAtPosition(5, 2);
std::cout << "List after insertions: ";
list.display();

// Test sorting
std::cout << "\nSorting list..." << std::endl;
list.sort();
std::cout << "Sorted list: ";
list.display();

// Test searching
int searchValue = 5;
std::cout << "\nSearching for " << searchValue << "..." << std::endl;
if (list.search(searchValue)) {
std::cout << "Found " << searchValue << " at position " <<
list.findPosition(searchValue) << std::endl;
}

// Test updating
std::cout << "\nUpdating 5 to 6..." << std::endl;
list.updateNode(5, 6);
std::cout << "List after update: ";
list.display();

// Test deletion
std::cout << "\nDeleting node with value 3..." << std::endl;
list.deleteNode(3);
std::cout << "List after deletion: ";
list.display();

// Test reverse
std::cout << "\nReversing list..." << std::endl;
list.reverse();
std::cout << "Reversed list: ";
list.display();

} catch (const std::exception& e) {


std::cerr << "Error: " << e.what() << std::endl;
return 1;
}

return 0;
}

Tree Questions
1. Take a binary tree and do tree traversals
#include <iostream>
using namespace std;

struct NodeTree {
int data;
NodeTree *left, *right;
NodeTree(int val) : data(val), left(nullptr), right(nullptr) {}
};

class BinaryTree {
public:
void inOrder(NodeTree *node) { if (node) { inOrder(node->left); cout << node->data << " ";
inOrder(node->right); } }
void preOrder(NodeTree *node) { if (node) { cout << node->data << " "; preOrder(node->left);
preOrder(node->right); } }
void postOrder(NodeTree *node) { if (node) { postOrder(node->left); postOrder(node->right); cout
<< node->data << " "; } }
};
int main() {
NodeTree *root = new NodeTree(59);
root->left = new NodeTree(43);
root->right = new NodeTree(68);
root->left->left = new NodeTree(32);
root->left->right = new NodeTree(50);

BinaryTree tree;
tree.inOrder(root);
cout << endl;
tree.preOrder(root);
cout << endl;
tree.postOrder(root);
cout << endl;
return 0;
}

2. Construct a BST and do the following on it:


a) Insert
b) Delete
c) Search
d) Max
e) Min
f) Predecessor
g) Successor

#include <iostream>
#include <stdexcept>
#include <stack>

class BST {
private:
struct Node {
int data;
Node *left, *right;
explicit Node(int val) : data(val), left(nullptr), right(nullptr) {}
};

Node* root;

// Helper method to clean up memory


void destroyTree(Node* node) {
if (node) {
destroyTree(node->left);
destroyTree(node->right);
delete node;
}
}

Node* insert(Node* node, int val) {


if (!node) return new Node(val);
if (val < node->data) node->left = insert(node->left, val);
else if (val > node->data) node->right = insert(node->right, val);
return node;
}

Node* deleteNode(Node* node, int key) {


if (!node) return nullptr;

if (key < node->data) {


node->left = deleteNode(node->left, key);
} else if (key > node->data) {
node->right = deleteNode(node->right, key);
} else {
// Node with only one child or no child
if (!node->left) {
Node* temp = node->right;
delete node;
return temp;
} else if (!node->right) {
Node* temp = node->left;
delete node;
return temp;
}

// Node with two children: Get the inorder successor (smallest


// in the right subtree)
Node* temp = minValueNode(node->right);
node->data = temp->data;
node->right = deleteNode(node->right, temp->data);
}
return node;
}

Node* minValueNode(Node* node) const {


if (!node) return nullptr;
while (node->left) node = node->left;
return node;
}

Node* maxValueNode(Node* node) const {


if (!node) return nullptr;
while (node->right) node = node->right;
return node;
}

Node* search(Node* node, int key) const {


if (!node || node->data == key) return node;
return (key < node->data) ? search(node->left, key) : search(node->right, key);
}
void inorderTraversal(Node* node, std::ostream& out) const {
if (node) {
inorderTraversal(node->left, out);
out << node->data << " ";
inorderTraversal(node->right, out);
}
}

public:
BST() : root(nullptr) {}

// Destructor to prevent memory leaks


~BST() {
destroyTree(root);
}

// Delete copy constructor and assignment operator to prevent shallow copying


BST(const BST&) = delete;
BST& operator=(const BST&) = delete;

void insert(int val) {


root = insert(root, val);
}

void remove(int key) {


if (!search(root, key)) {
throw std::runtime_error("Key not found in the tree");
}
root = deleteNode(root, key);
}

bool contains(int key) const {


return search(root, key) != nullptr;
}

int minValue() const {


if (!root) throw std::runtime_error("Tree is empty");
return minValueNode(root)->data;
}

int maxValue() const {


if (!root) throw std::runtime_error("Tree is empty");
return maxValueNode(root)->data;
}

int predecessor(int key) const {


Node* current = root;
Node* pred = nullptr;

while (current) {
if (key > current->data) {
pred = current;
current = current->right;
} else {
current = current->left;
}
}
if (!pred) throw std::runtime_error("No predecessor found");
return pred->data;
}

int successor(int key) const {


Node* current = root;
Node* succ = nullptr;

while (current) {
if (key < current->data) {
succ = current;
current = current->left;
} else {
current = current->right;
}
}

if (!succ) throw std::runtime_error("No successor found");


return succ->data;
}

bool empty() const {


return root == nullptr;
}

void display(std::ostream& out = std::cout) const {


if (empty()) {
out << "Empty tree" << std::endl;
return;
}
inorderTraversal(root, out);
out << std::endl;
}
};

int main() {
try {
BST bst;

// Test insertion
bst.insert(45);
bst.insert(25);
bst.insert(65);
bst.insert(15);
bst.insert(35);
bst.insert(55);
bst.insert(75);

std::cout << "Inorder traversal of the BST: ";


bst.display();

// Test deletion
bst.remove(15);
std::cout << "After deleting 15: ";
bst.display();
// Test search
int key = 35;
std::cout << "Search " << key << ": " << (bst.contains(key) ? "Found" : "Not Found") <<
std::endl;

// Test min/max
std::cout << "Minimum value: " << bst.minValue() << std::endl;
std::cout << "Maximum value: " << bst.maxValue() << std::endl;

// Test predecessor/successor
std::cout << "Predecessor of 35: " << bst.predecessor(35) << std::endl;
std::cout << "Successor of 35: " << bst.successor(35) << std::endl;

} catch (const std::exception& e) {


std::cerr << "Error: " << e.what() << std::endl;
return 1;
}

return 0;
}

You might also like