diff --git a/src/Algorithms/sort.hpp b/src/Algorithms/sort.hpp index dc84bd9..f7b3fb0 100644 --- a/src/Algorithms/sort.hpp +++ b/src/Algorithms/sort.hpp @@ -1,7 +1,7 @@ #pragma once #include -namespace algorithms +namespace mystd { template diff --git a/src/Data_Structures/Deque.hpp b/src/Data_Structures/Deque.hpp index dadb972..8d13865 100644 --- a/src/Data_Structures/Deque.hpp +++ b/src/Data_Structures/Deque.hpp @@ -71,7 +71,7 @@ template class deque currSize++; } - const T &pop_front() + T pop_front() { if (currSize == 0) { @@ -83,7 +83,7 @@ template class deque return toRet; } - const T &pop_back() + T pop_back() { if (currSize == 0) { diff --git a/src/Data_Structures/Priority_Queue.hpp b/src/Data_Structures/Priority_Queue.hpp new file mode 100644 index 0000000..0632590 --- /dev/null +++ b/src/Data_Structures/Priority_Queue.hpp @@ -0,0 +1,93 @@ +#pragma once +#include +#include +#include +#include +#include + +namespace mystd +{ +template class priority_queue +{ + public: + priority_queue() : tree(4) + { + sz = 0; + maxSz = 4; + } + + void push(T item) + { + if (sz == maxSz) + { + reallocate(maxSz + maxSz / 2); + } + tree[sz] = item; + size_t currInd = sz; + while (currInd != 0 && tree[(currInd - 1) / 2] < tree[currInd]) + { + std::swap(tree[currInd], tree[(currInd - 1) / 2]); + currInd = (currInd - 1) / 2; + } + sz++; + } + + const T &top() const + { + if (sz == 0) + { + throw std::out_of_range("No items in Priority Queue."); + } + return tree[0]; + } + + T pop() + { + if (sz == 0) + { + throw std::out_of_range("No items in Priority Queue."); + } + T toRet = tree[0]; + tree[0] = std::move(tree[sz - 1]); + sz--; + heapify(0); + return toRet; + } + + bool empty() const { return sz == 0; } + + size_t size() const { return sz; } + + private: + void heapify(size_t currInd) + { + const size_t left = currInd * 2 + 1; + const size_t right = currInd * 2 + 2; + size_t newLargest = currInd; + if (left < sz && tree[left] > tree[newLargest]) + newLargest = left; + if (right < sz && tree[right] > tree[newLargest]) + newLargest = right; + if (newLargest != currInd) + { + std::swap(tree[currInd], tree[newLargest]); + heapify(newLargest); + } + } + + void reallocate(size_t newSize) + { + array newTree = array(newSize); + for (size_t i = 0; i < sz; i++) + { + newTree[i] = std::move(tree[i]); + } + tree = std::move(newTree); + maxSz = newSize; + } + + array tree; + size_t sz; + size_t maxSz; +}; +} // namespace mystd \ No newline at end of file diff --git a/src/Data_Structures/Queue.hpp b/src/Data_Structures/Queue.hpp index 024d747..1315631 100644 --- a/src/Data_Structures/Queue.hpp +++ b/src/Data_Structures/Queue.hpp @@ -46,7 +46,7 @@ template class queue currSize++; } - const T &pop() + T pop() { if (currSize == 0) { diff --git a/src/Data_Structures/Ringbuffer.hpp b/src/Data_Structures/Ringbuffer.hpp index 9ee986a..1a9f2d2 100644 --- a/src/Data_Structures/Ringbuffer.hpp +++ b/src/Data_Structures/Ringbuffer.hpp @@ -29,7 +29,7 @@ template class ringbuffer currSize++; } - const T &get_item() + T get_item() { if (currSize == 0) { diff --git a/src/Data_Structures/Stack.hpp b/src/Data_Structures/Stack.hpp index be3f6cc..cff7e50 100644 --- a/src/Data_Structures/Stack.hpp +++ b/src/Data_Structures/Stack.hpp @@ -14,7 +14,7 @@ template class stack void push(T item) { data.push_back(item); } - const T &pop() { return data.pop_back(); } + T pop() { return data.pop_back(); } T &top() { diff --git a/src/Data_Structures/Vector.hpp b/src/Data_Structures/Vector.hpp index ce0233c..36fe1ac 100644 --- a/src/Data_Structures/Vector.hpp +++ b/src/Data_Structures/Vector.hpp @@ -39,14 +39,14 @@ template class vector currSize++; } - const T &pop_back() + T pop_back() { if (currSize == 0) { // std::cout << "No items in vector\n"; throw std::out_of_range("No items."); } - T &ret = data[currSize - 1]; + T ret = data[currSize - 1]; currSize--; return ret; } diff --git a/tst/test_priority_queue.cpp b/tst/test_priority_queue.cpp new file mode 100644 index 0000000..10551b6 --- /dev/null +++ b/tst/test_priority_queue.cpp @@ -0,0 +1,103 @@ +#include +#include +#include + +using namespace mystd; + +TEST(PriorityTest, InitializeEmpty) +{ + priority_queue pq; + ASSERT_EQ(pq.size(), 0); + ASSERT_TRUE(pq.empty()); + ASSERT_THROW(pq.pop(), std::out_of_range); +} + +TEST(PriorityTest, PushPopSingle) +{ + priority_queue pq; + pq.push(42); + ASSERT_EQ(pq.size(), 1); + ASSERT_EQ(pq.pop(), 42); + ASSERT_TRUE(pq.empty()); +} + +TEST(PriorityTest, PushMultipleMaintainsOrder) +{ + priority_queue pq; + pq.push(10); + pq.push(50); + pq.push(20); + pq.push(40); + pq.push(30); + + ASSERT_EQ(pq.size(), 5); + ASSERT_EQ(pq.pop(), 50); + ASSERT_EQ(pq.pop(), 40); + ASSERT_EQ(pq.pop(), 30); + ASSERT_EQ(pq.pop(), 20); + ASSERT_EQ(pq.pop(), 10); + ASSERT_TRUE(pq.empty()); +} + +TEST(PriorityTest, HandlesDuplicatesCorrectly) +{ + priority_queue pq; + pq.push(5); + pq.push(5); + pq.push(5); + ASSERT_EQ(pq.size(), 3); + + ASSERT_EQ(pq.pop(), 5); + ASSERT_EQ(pq.pop(), 5); + ASSERT_EQ(pq.pop(), 5); + ASSERT_TRUE(pq.empty()); +} + +TEST(PriorityTest, HandlesNegativeNumbers) +{ + priority_queue pq; + pq.push(-10); + pq.push(0); + pq.push(-5); + pq.push(5); + + ASSERT_EQ(pq.pop(), 5); + ASSERT_EQ(pq.pop(), 0); + ASSERT_EQ(pq.pop(), -5); + ASSERT_EQ(pq.pop(), -10); + ASSERT_TRUE(pq.empty()); +} + +TEST(PriorityTest, StressTestLargeNumberOfElements) +{ + priority_queue pq; + int N = 1000; + + for (int i = 0; i < N; ++i) + { + pq.push(i); + } + ASSERT_EQ(pq.size(), N); + + for (int i = N - 1; i >= 0; --i) + { + ASSERT_EQ(pq.pop(), i); + } + ASSERT_TRUE(pq.empty()); +} + +TEST(PriorityTest, InterleavedPushPopOperations) +{ + priority_queue pq; + pq.push(10); + pq.push(20); + ASSERT_EQ(pq.pop(), 20); + pq.push(15); + ASSERT_EQ(pq.pop(), 15); + pq.push(30); + pq.push(25); + ASSERT_EQ(pq.pop(), 30); + ASSERT_EQ(pq.pop(), 25); + ASSERT_EQ(pq.pop(), 10); + ASSERT_TRUE(pq.empty()); +}