Skip to content

Commit

Permalink
Федорец Илья - Лабораторная работа №2 (#415)
Browse files Browse the repository at this point in the history
* initial

* fixes

* fixes

* fixes

* fixes

* fixes
  • Loading branch information
ilya-fedorets authored Dec 2, 2024
1 parent b82fba7 commit f575f14
Show file tree
Hide file tree
Showing 7 changed files with 518 additions and 0 deletions.
12 changes: 12 additions & 0 deletions modules/fedorets_i_leftheap/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Declare variables for binaries' names
get_filename_component(DIR_NAME ${CMAKE_CURRENT_LIST_DIR} NAME)
set(MODULE "${DIR_NAME}")
set(LIBRARY "lib_${MODULE}")
set(TESTS "test_${MODULE}")

# Include directory with public headers
include_directories(${CMAKE_CURRENT_SOURCE_DIR})

# Add all submodules
add_subdirectory(src)
add_subdirectory(test)
58 changes: 58 additions & 0 deletions modules/fedorets_i_leftheap/include/leftheap.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// Copyright 2024 Fedorets Ilya

#ifndef MODULES_FEDORETS_I_LEFTHEAP_INCLUDE_LEFTHEAP_H_
#define MODULES_FEDORETS_I_LEFTHEAP_INCLUDE_LEFTHEAP_H_

#include <algorithm>
#include <iostream>

class LeftistHeap {
private:
struct Node {
int data;
int rank;
Node* left;
Node* right;

explicit Node(int val)
: data(val), rank(1), left(nullptr), right(nullptr) {}

explicit Node(const Node* other)
: data(other->data), rank(other->rank), left(nullptr), right(nullptr) {
if (other->left) left = new Node(other->left);
if (other->right) right = new Node(other->right);
}
};

Node* root;

Node* deepCopy(const Node* node);
Node* merge(Node* h1, Node* h2);
void deleteNode(Node* node);

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

LeftistHeap(const LeftistHeap& other) : root(deepCopy(other.root)) {}

LeftistHeap(LeftistHeap&& other) noexcept : root(other.root) {
other.root = nullptr;
}

LeftistHeap& operator=(const LeftistHeap& other);
LeftistHeap& operator=(LeftistHeap&& other) noexcept;

~LeftistHeap() { deleteNode(root); }

void insert(int val);
void merge(LeftistHeap& other);
int deleteMin();
bool isEmpty() const;
int findMin() const;
int size() const;

private:
int countNodes(Node* node) const;
};

#endif // MODULES_FEDORETS_I_LEFTHEAP_INCLUDE_LEFTHEAP_H_
18 changes: 18 additions & 0 deletions modules/fedorets_i_leftheap/src/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
set(target ${LIBRARY})

file(GLOB srcs "*.cpp")
file(GLOB hdrs "../include/*.h")
set_source_files_properties(${srcs} ${hdrs} PROPERTIES
LABELS "${MODULE};Library")

add_library(${target} STATIC ${srcs} ${hdrs})
set_target_properties(${target} PROPERTIES
OUTPUT_NAME ${MODULE}
LABELS "${MODULE};Library")

if (UNIX)
target_link_libraries(${target} ${CMAKE_THREAD_LIBS_INIT})
endif (UNIX)
target_link_libraries(${target} ${LIBRARY_DEPS})

set(LIBRARY_DEPS "${LIBRARY_DEPS};${target}" PARENT_SCOPE)
91 changes: 91 additions & 0 deletions modules/fedorets_i_leftheap/src/leftheap.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
// Copyright 2024 Fedorets Ilya

#include "include/leftheap.h"

LeftistHeap::Node* LeftistHeap::deepCopy(const Node* node) {
return node ? new Node(node) : nullptr;
}

LeftistHeap::Node* LeftistHeap::merge(Node* h1, Node* h2) {
if (h1 == nullptr) return h2;
if (h2 == nullptr) return h1;

if (h1->data > h2->data) {
std::swap(h1, h2);
}

h1->right = merge(h1->right, h2);

if (h1->left == nullptr ||
(h1->right != nullptr && h1->right->rank > h1->left->rank)) {
std::swap(h1->left, h1->right);
}

h1->rank = (h1->right ? h1->right->rank : 0) + 1;

return h1;
}

void LeftistHeap::deleteNode(Node* node) {
if (node == nullptr) return;
deleteNode(node->left);
deleteNode(node->right);
delete node;
}

LeftistHeap& LeftistHeap::operator=(const LeftistHeap& other) {
if (this != &other) {
deleteNode(root);

root = deepCopy(other.root);
}
return *this;
}

LeftistHeap& LeftistHeap::operator=(LeftistHeap&& other) noexcept {
if (this != &other) {
deleteNode(root);

root = other.root;
other.root = nullptr;
}
return *this;
}

void LeftistHeap::insert(int val) {
Node* newNode = new Node(val);
root = merge(root, newNode);
}

void LeftistHeap::merge(LeftistHeap& other) {
root = merge(root, other.root);
other.root = nullptr;
}

int LeftistHeap::deleteMin() {
if (root == nullptr) {
throw std::runtime_error("Heap is empty");
}

int minVal = root->data;
Node* oldRoot = root;
root = merge(root->left, root->right);
delete oldRoot;

return minVal;
}

bool LeftistHeap::isEmpty() const { return root == nullptr; }

int LeftistHeap::findMin() const {
if (root == nullptr) {
throw std::runtime_error("Heap is empty");
}
return root->data;
}

int LeftistHeap::size() const { return countNodes(root); }
int LeftistHeap::countNodes(Node* node) const {
if (node == nullptr) return 0;
return 1 + countNodes(node->left) + countNodes(node->right);
}
27 changes: 27 additions & 0 deletions modules/fedorets_i_leftheap/test/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
set(target ${TESTS})

file(GLOB srcs "*.cpp")
set_source_files_properties(${srcs} PROPERTIES
LABELS "${MODULE};Test")

add_executable(${target} ${srcs} ${hdrs})
set_target_properties(${target} PROPERTIES
LABELS "${MODULE};Test")

if (UNIX)
target_link_libraries(${target} gtest ${CMAKE_THREAD_LIBS_INIT} pthread)
endif (UNIX)
target_link_libraries(${target} gtest ${LIBRARY})

# VS2012 doesn't support correctly the tuples yet,
# see http://code.google.com/p/googletest/issues/detail?id=412
if(MSVC)
target_compile_definitions(${target} PUBLIC _VARIADIC_MAX=10)
endif()

add_test(
NAME ${MODULE}_gtest
COMMAND ${target}
)
set_tests_properties (${MODULE}_gtest PROPERTIES
LABELS "${MODULE}")
Loading

0 comments on commit f575f14

Please sign in to comment.