Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: implement merge sort algorithm #1

Merged
merged 2 commits into from
Nov 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ cmake_minimum_required(VERSION 3.10)

project(MergeSort)

set(SOURCES src/main.cpp)
include_directories(src/app src/merge_sorter)

set(SOURCES src/main.cpp src/app/app.cpp src/merge_sorter/merge_sorter.cpp)

add_executable(MergeSort ${SOURCES})

Expand Down
126 changes: 126 additions & 0 deletions src/app/app.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
/**
* @file app.cpp
* @author Mateusz Basiaga (basmateusz@wp.pl)
* @brief
* @date 2024-11-13
*
* @copyright Copyright (c) 2024
*
*/

#ifdef _WIN32
#include <windows.h>
#endif

#include "app.hpp"
#include "../merge_sorter/merge_sorter.hpp"

std::istream& operator>>(std::istream& iStream, MenuOption& menuOption) {
int num;
iStream >> num;
menuOption = static_cast<MenuOption>(num);

return iStream;
}

std::vector<int> App::array;

int App::mainMenu() {
while (true) {
std::cout << "MENU:\n\n";

std::cout << "---ZARZĄDZANIE ELEMENTAMI LISTY---\n";
std::cout << "1. Dodaj element\n\n";

std::cout << "---ZARZĄDZANIE LISTĄ---\n";
std::cout << "2. Wyświetl zawrtość\n";
std::cout << "3. Posortuj\n";
std::cout << "4. Wyczyść\n\n";

std::cout << "---OPCJE---\n";
std::cout << "5. Wyjdź\n\n";

std::cout << "Wybierz działanie: ";

MenuOption selectedOption;

std::cin >> selectedOption;

if (selectedOption > EXIT) {
std::cout << "Nieprawidłowa opcja, spróbuj ponownie\n\n";
continue;
}

std::cout << std::endl;

switch (selectedOption) {
case INSERT_ITEM:
handleInsertItem();
break;
case DISPLAY_ARRAY:
handleDisplayArray();
break;
case SORT_ARRAY:
handleSortArray();
break;
case CLEAR_ARRAY:
handleClearArray();
break;
case EXIT: {
return handleExit();
}
default:
std::cout << "Nieprawidłowa opcja, spróbuj ponownie\n";
}

std::cout << "\n";
}
}


int App::run() {
#ifdef _WIN32
// enable utf-8 printing on windows
SetConsoleOutputCP(CP_UTF8);
#endif

int exitCode = mainMenu();
return exitCode;
}

void App::handleInsertItem() {
std::cout << "Podaj wartość: ";
int value;
std::cin >> value;

array.push_back(value);
}

void App::handleDisplayArray() {
std::cout << "[";

for (auto it = array.begin(); it != array.end(); ++it) {
std::cout << *it;

if (it != array.end() - 1) {
std::cout << ", ";
}
}

std::cout << "]\n";
}

void App::handleClearArray() {
array.clear();
std::cout << "Wyczyszczono listę\n";
}

void App::handleSortArray() {
array = MergeSorter::sortArray(array);
std::cout << "Posortowano listę\n";
}

int App::handleExit() {
std::cout << "Dziękujemy za korzystanie z programu\n";
return 0;
}
68 changes: 68 additions & 0 deletions src/app/app.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/**
* @file app.hpp
* @author Mateusz Basiaga (basmateusz@wp.pl)
* @brief
* @date 2024-11-13
*
* @copyright Copyright (c) 2024
*
*/

#ifndef APP_HPP
#define APP_HPP

#include <iostream>
#include <vector>

/// @brief Wyliczenie opcji dostępnych w menu.
/// Definiuje różne operacje, które użytkownik może wybrać w aplikacji.
enum MenuOption {
INSERT_ITEM = 1,

DISPLAY_ARRAY,
SORT_ARRAY,
CLEAR_ARRAY,

EXIT ///< Zakończenie działania aplikacji.
};

/// @brief Przeciążenie operatora >> do wyboru opcji menu.
/// @param iStream Strumień wejściowy.
/// @param menuOption Opcja menu, którą należy ustawić.
/// @return Referencja do strumienia wejściowego.
std::istream& operator>>(std::istream& iStream, MenuOption& menuOption);

/// @brief Klasa reprezentująca aplikację obsługującą listę.
/// Umożliwia operacje takie jak dodawanie, usuwanie i wyświetlanie elementów oraz sortowanie listy poprzez menu.
class App {
private:
static std::vector<int> array;

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

/// @brief Wyświetla główne menu aplikacji i zwraca wybraną opcję.
/// @return Wybrana opcja menu.
static int mainMenu();

static void handleInsertItem();

static void handleDisplayArray();

static void handleClearArray();

static void handleSortArray();

/// @brief Obsługuje zakończenie działania aplikacji.
/// @return Kod wyjścia z aplikacji.
static int handleExit();

public:
/// @brief Uruchamia aplikację.
/// Wyświetla menu i pozwala użytkownikowi wykonywać operacje na liście.
/// @return Kod zakończenia aplikacji.
static int run();
};

#endif /* APP_HPP */
14 changes: 11 additions & 3 deletions src/main.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
#include <iostream>
/**
* @file main.cpp
* @author Mateusz Basiaga (basmateusz@wp.pl)
* @brief
* @date 2024-11-13
*
* @copyright Copyright (c) 2024
*
*/

#include "main.h"
#include "app/app.hpp"

int main() {
std::cout << "Hello world!";
return App::run();
}
10 changes: 0 additions & 10 deletions src/main.h

This file was deleted.

82 changes: 82 additions & 0 deletions src/merge_sorter/merge_sorter.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/**
* @file merge_sorter.cpp
* @author Mateusz Basiaga (basmateusz@wp.pl)
* @brief
* @date 2024-11-13
*
* @copyright Copyright (c) 2024
*
*/

#include <vector>

#include "merge_sorter.hpp"

std::vector<int> MergeSorter::merge(std::vector<int> arr, int left, int mid, int right) {

int leftSize = mid - left + 1;
int rightSize = right - mid;

std::vector<int> L(leftSize);
std::vector<int> M(rightSize);

// Wypełnienie tablicy L danymi z lewej części głównej tablicy
for (int i = 0; i < leftSize; i++)
L[i] = arr[left + i];

// Wypełnienie tablicy M danymi z prawej części głównej tablicy
for (int j = 0; j < rightSize; j++)
M[j] = arr[mid + 1 + j];

// Pozostawienie bieżących indeksów w podtablicach oraz w głównej tablicy
int i = 0, j = 0, k = left;

// Dopóki nie osiągniemy końca jednej z podtablic L lub M,
// wybieramy mniejszy element z L lub M i umieszcamy go we właściwej pozycji w A[left..right]
while (i < leftSize && j < rightSize) {
if (L[i] <= M[j]) {
arr[k] = L[i];
i++;
} else {
arr[k] = M[j];
j++;
}
k++;
}

// Gdy skończą się elementy w jednej z podtablic L lub M,
// przenosimy pozostałe elementy do A[left..right]
while (i < leftSize) {
arr[k] = L[i];
i++;
k++;
}

while (j < rightSize) {
arr[k] = M[j];
j++;
k++;
}

return arr;
}

std::vector<int> MergeSorter::mergeSort(std::vector<int>& arr, int left, int right) {
if (left < right) {
// mid jest punktem, w którym tablica jest dzielona na dwie podtablice
int mid = left + (right - left) / 2;

// Wywołujemy rekurencyjnie sortowanie dla lewej i prawej części
mergeSort(arr, left, mid);
mergeSort(arr, mid + 1, right);

// Scalamy posortowane podtablice
arr = merge(arr, left, mid, right);
}

return arr;
}

std::vector<int> MergeSorter::sortArray(std::vector<int>& arr) {
return mergeSort(arr, 0, (int)arr.size() - 1);
}
19 changes: 19 additions & 0 deletions src/merge_sorter/merge_sorter.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#ifndef MERGE_SORTER_HPP
#define MERGE_SORTER_HPP

#include <vector>

class MergeSorter {
private:
MergeSorter() = delete;
MergeSorter(const MergeSorter&) = delete;
MergeSorter& operator=(const MergeSorter&) = delete;

static std::vector<int> merge(std::vector<int> arr, int left, int mid, int right);
static std::vector<int> mergeSort(std::vector<int>& arr, int left, int right);

public:
static std::vector<int> sortArray(std::vector<int>& arr);
};

#endif /* MERGE_SORTER_HPP */
Loading