Completed BST and most of infrastructure for the whole section

This commit is contained in:
Christopher Sanden
2025-11-07 22:27:11 +01:00
parent e761ac0e23
commit d6d627adad
13 changed files with 449 additions and 22 deletions

View File

@@ -4,12 +4,12 @@
#include "option1.h"
#include <iostream>
#include "TDoublyLinkedList.h"
#include "TQueue.h"
#include "TTreeQueue.h"
#include "TStack.h"
#include "Utils.h"
TDoublyLinkedList document;
TQueue printQueue;
TTreeQueue printQueue;
TStack undoStack, redoStack;
bool running = true;

View File

@@ -40,8 +40,8 @@ int RunApp()
TPerson* employeeAlphaSort[e.GetSize()];
printline();
for (int i = 0; i < e.GetSize(); i++) {
//std::cout << "[" << i << "] " << e.GetAtIndex(i).lastName << ", " << e.GetAtIndex(i).firstName
//<< " | status: Employee | cabin size: " << e.GetAtIndex(i).cabinSize << std::endl;
std::cout << "[" << i << "] " << e.GetAtIndex(i).lastName << ", " << e.GetAtIndex(i).firstName
<< " | status: Employee | cabin size: " << e.GetAtIndex(i).cabinSize << std::endl;
employeeAlphaSort[i] = new TPerson(e.GetAtIndex(i));
}
printline();
@@ -49,8 +49,8 @@ int RunApp()
TPerson* guestAlphaSort[g.GetSize()];
printline();
for (int i = 0; i < g.GetSize(); i++) {
//std::cout << "[" << i << "] " << g.GetAtIndex(i).lastName << ", " << g.GetAtIndex(i).firstName
//<< " | status: Guest | cabin size: " << g.GetAtIndex(i).cabinSize << std::endl;
std::cout << "[" << i << "] " << g.GetAtIndex(i).lastName << ", " << g.GetAtIndex(i).firstName
<< " | status: Guest | cabin size: " << g.GetAtIndex(i).cabinSize << std::endl;
guestAlphaSort[i] = new TPerson(g.GetAtIndex(i));
}
printline();

View File

@@ -7,6 +7,10 @@ option(BUILD_ASSIGNMENT_03_OPTION_1 "Build Assignment Option 1 (Standard)" ON)
add_executable(Assignment-03
main.cpp
TBST.cpp
TBST.h
TEmployee.h
TTreeQueue.cpp
)
# Conditionally add the correct source file

View File

@@ -0,0 +1,182 @@
#include "TBST.h"
#include <iostream>
#include "TTreeQueue.h"
void TBST::destroy(Node *node)
{
if (!node)
return;
destroy(node->left);
destroy(node->right);
delete node->data;
delete node;
}
void TBST::Insert(const int key, TEmployee *data)
{
root = insert(root, key, data);
}
Node* TBST::insert(Node* node, const int key, TEmployee *data)
{
if (node == nullptr) {
auto* n = new Node{key, data, nullptr, nullptr};
return n;
}
if (key < node->key)
node->left = insert(node->left, key, data);
else if (key > node->key)
node->right = insert(node->right, key, data);
else
std::cout << "Error with node insertion" << std::endl;
return node;
}
TEmployee *TBST::Search(int key) const
{
const Node* result = search(root, key);
return result ? result->data : nullptr;
}
Node* TBST::search(Node* node, const int key)
{
if (node == nullptr)
return nullptr;
if (key == node->key)
return node;
if (key < node->key)
return search(node->left, key);
else
return search(node->right, key);
}
void TBST::Delete(const int key)
{
root = remove(root, key);
}
Node *TBST::remove(Node *node, const int key)
{
if (node == nullptr)
return nullptr;
if (key < node->key)
node->left = remove(node->left, key);
else if (key > node->key)
node->right = remove(node->right, key);
else {
// No children
if (node->left == nullptr && node->right == nullptr) {
delete node->data;
delete node;
return nullptr;
}
// Right child only
if (node->left == nullptr) {
Node* child = node->right;
delete node->data;
delete node;
return child;
}
// Left child only
if (node->right == nullptr) {
Node* child = node->left;
delete node->data;
delete node;
return child;
}
// Two children
else {
Node* minRight = findMin(node->right);
node->key = minRight->key;
node->data = minRight->data;
node->right = remove(minRight->right, minRight->key);
}
}
return node;
}
Node* TBST::findMin(Node* node)
{
while (node && node->left)
node = node->left;
return node;
}
/// Traversals
/// Private helpers
void TBST::preorder(const Node* node)
{
if (!node)
return;
std::cout << "[" << node->key << "] ";
preorder(node->left);
preorder(node->right);
}
void TBST::inorder(const Node* node)
{
if (!node)
return;
inorder(node->left);
std::cout << "[" << node->key << "] ";
inorder(node->right);
}
void TBST::postorder(const Node *node)
{
if (!node)
return;
postorder(node->left);
postorder(node->right);
std::cout << "[" << node->key << "] ";
}
void TBST::levelorder(const Node* node)
{
if (!node)
return;
TTreeQueue q;
q.Enqueue(const_cast<Node*>(node));
while (!q.IsEmpty()) {
const Node* cur = q.Dequeue();
std::cout << "[" << cur->key << "] ";
if (cur->left)
q.Enqueue(cur->left);
if (cur->right)
q.Enqueue(cur->right);
}
}
void TBST::Inorder() const
{
inorder(root);
std::cout << std::endl;
}
void TBST::Preorder() const
{
preorder(root);
std::cout << std::endl;
}
void TBST::Postorder() const
{
postorder(root);
std::cout << std::endl;
}
void TBST::LevelOrder() const
{
levelorder(root);
std::cout << std::endl;
}

View File

@@ -0,0 +1,52 @@
#ifndef IKT203_COURSE_ASSIGNMENTS_TBST_H
#define IKT203_COURSE_ASSIGNMENTS_TBST_H
#include "TEmployee.h"
struct Node {
int key;
TEmployee* data;
Node* left;
Node* right;
};
class TBST {
private:
Node* root;
static Node* insert(Node* node, int key, TEmployee* data);
static Node* search(Node* node, int key);
static Node* remove(Node* node, int key);
static void inorder(const Node* node);
static void preorder(const Node* node);
static void postorder(const Node* node);
static void levelorder(const Node* node);
static void destroy(Node* node);
static Node* findMin(Node* node);
public:
TBST() = default;
~TBST() {destroy(root);}
void Insert(int key, TEmployee* data);
[[nodiscard]] TEmployee* Search(int key) const;
void Delete(int key);
void Inorder() const;
void Preorder() const;
void Postorder() const;
void LevelOrder() const;
};
#endif //IKT203_COURSE_ASSIGNMENTS_TBST_H

View File

@@ -0,0 +1,26 @@
#ifndef IKT203_COURSE_ASSIGNMENTS_TEMPLOYEE_H
#define IKT203_COURSE_ASSIGNMENTS_TEMPLOYEE_H
#include <string>
#include <utility>
struct TEmployee {
std::string firstName;
std::string lastName;
int id;
TEmployee(std::string f, std::string l) : firstName(std::move(f)), lastName(std::move(l)) {};
~TEmployee() = default;
};
#endif //IKT203_COURSE_ASSIGNMENTS_TEMPLOYEE_H

View File

@@ -0,0 +1,37 @@
#include "TTreeQueue.h"
#include <stdexcept>
void TTreeQueue::Enqueue(Node* n)
{
if (n == nullptr)
return;
if (IsFull())
throw std::overflow_error("Queue Overflow");
queue[tail] = n;
tail = (tail + 1) % MAX_SIZE;
count++;
}
Node* TTreeQueue::Dequeue()
{
if (IsEmpty())
throw std::underflow_error("Empty Queue");
Node* n = queue[head];
if (n == nullptr)
return nullptr;
head = (head + 1) % MAX_SIZE;
count--;
return n;
}
bool TTreeQueue::IsEmpty() const
{
return count == 0;
}
bool TTreeQueue::IsFull() const
{
return count == MAX_SIZE;
}

View File

@@ -0,0 +1,27 @@
#ifndef TQUEUE_H
#define TQUEUE_H
#define MAX_SIZE 200
#include "TBST.h"
struct TTreeQueue {
Node* queue[MAX_SIZE];
int head = 0;
int tail = 0;
int count = 0;
TTreeQueue() = default;
~TTreeQueue() = default;
void Enqueue(Node* n);
Node* Dequeue();
[[nodiscard]] bool IsEmpty() const;
[[nodiscard]] bool IsFull() const;
};
#endif //TQUEUE_H

View File

@@ -1,6 +1,53 @@
#include "option1.h"
#include <limits>
int RunApp() {
// Implement the Console Text Editor application logic here
return 0;
}
bst = new TBST();
/* Path to the names data file
This is MY absolute path -- change to your local path for this to read properly
something like "C:\Users\Username\FolderYouSavedTheSubmissionIn\Exam\IKT203Exam\DATA\random_names.txt"
Double slash is needed for string to pass the correct file path */
const std::string filename = "C:\\Users\\csand\\IKT203\\Exam\\IKT203Exam\\DATA\\random_names.txt";
readNamesFromFile(filename, onNameRead);
pack("Inorder traversal (sorted by ID)");
bst->Inorder();
pack("Level order traversal");
bst->LevelOrder();
pack("Preorder traversal");
bst->Preorder();
pack("Postorder traversal");
bst->Postorder();
pack("Search function");
std::cout << "\nInput the ID you want to search for\n" << std::endl;
int choice;
std::cin >> choice;
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
if (const TEmployee* result = bst->Search(choice))
std::cout << "Match found:\n" << result->firstName << " " << result->lastName << std::endl;
else
std::cout << "ID not found" << std::endl;
pack("Remove function");
std::cout << "\nInput the ID you want to remove\n" << std::endl;
std::cin >> choice;
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
if (const TEmployee* res = bst->Search(choice)) {
bst->Delete(choice);
std::cout << "ID removed\n" << std::endl;
}
else
std::cout << "ID not found\n" << std::endl;
bst->Inorder();
pack ("Cleaning up");
delete bst;
return 0;
}

View File

@@ -3,7 +3,57 @@
#ifndef OPTION1_H
#define OPTION1_H
#include <iostream>
#include <TTreeQueue.h>
#include <unordered_set>
#include "TBST.h"
#include "TEmployee.h"
#include "Utils.h"
#include "../../Submissions/Submission-04/BankAccount.h"
/// To keep track of used ID values to ensure
/// all unique IDs
inline std::unordered_set<int> usedIds;
static TBST* bst;
int RunApp();
inline void IdGenerator(TEmployee* employee)
{
int id = Utils::RandomInt(1, 1000);
while (usedIds.count(id) > 0)
id = Utils::RandomInt(1, 1000);
usedIds.insert(id);
employee->id = id;
}
static bool onNameRead(const int index, const int aTotalCount, const std::string& aFirstName, const std::string& aLastName)
{
const auto e = new TEmployee(aFirstName, aLastName);
if (index >= 200)
return false;
IdGenerator(e);
bst->Insert(e->id, e);
std::cout << "[" << e->id << "] " << e->firstName << ", " << e->lastName << std::endl;
return true;
}
inline void printline()
{
std::cout << "----------------------------------------" << std::endl;
}
inline void pack(const std::string& line)
{
std::cout << "\n\n\n" << std::endl;
printline();
std::cout << line << std::endl;
printline();
}
#endif // OPTION1_H

View File

@@ -6,7 +6,8 @@ add_library(SharedLib STATIC
TPerson.cpp
TPerson.h
TLinkedList.cpp
TLinkedList.h)
TLinkedList.h
../Assignment-03/TEmployee.h)
# --- Step 2: Add Header Files to the Library ---
@@ -18,7 +19,7 @@ target_sources(SharedLib
SharedLib.h
TDoublyLinkedList.h
TStack.h
TQueue.h
TTreeQueue.h
Utils.h
# Or add other shared files here
PRIVATE
@@ -28,7 +29,7 @@ target_sources(SharedLib
FileReaderUtils.cpp
TDoublyLinkedList.cpp
TStack.cpp
TQueue.cpp
TTreeQueue.cpp
Utils.cpp
)

View File

@@ -1,9 +1,9 @@
#include "TQueue.h"
#include "TTreeQueue.h"
#include <stdexcept>
void TQueue::Enqueue(const std::string& text)
void TTreeQueue::Enqueue(const std::string& text)
{
if (IsFull())
throw std::overflow_error("Queue Overflow");
@@ -12,7 +12,7 @@ void TQueue::Enqueue(const std::string& text)
count++;
}
std::string TQueue::Dequeue()
std::string TTreeQueue::Dequeue()
{
if (IsEmpty())
throw std::underflow_error("Empty Queue");
@@ -22,24 +22,24 @@ std::string TQueue::Dequeue()
return item;
}
std::string TQueue::Peek() const
std::string TTreeQueue::Peek() const
{
if (IsEmpty())
throw std::underflow_error("Empty Queue");
return queue[head];
}
bool TQueue::IsEmpty() const
bool TTreeQueue::IsEmpty() const
{
return count == 0;
}
bool TQueue::IsFull() const
bool TTreeQueue::IsFull() const
{
return count == MAX_SIZE;
}
int TQueue::GetTail() const
int TTreeQueue::GetTail() const
{
if (IsEmpty())
throw std::underflow_error("Empty Queue");

View File

@@ -5,7 +5,8 @@
#include "TDoublyLinkedList.h"
class TQueue {
class TTreeQueue {
private:
std::string queue[MAX_SIZE];
int head = 0;
@@ -13,8 +14,8 @@ private:
int count = 0;
public:
TQueue() = default;
~TQueue() = default;
TTreeQueue() = default;
~TTreeQueue() = default;
void Enqueue(const std::string& text);
std::string Dequeue();