From 7d466865f597acdc7f1f306edc6946d4202e1658 Mon Sep 17 00:00:00 2001 From: lifegpc Date: Thu, 20 Jun 2024 19:40:12 +0800 Subject: [PATCH] Add LinkedQueue --- linked_queue.h | 97 +++++++++++++++++++++++++++++++++++++++++++++ test/queue_test.cpp | 24 +++++++++++ 2 files changed, 121 insertions(+) create mode 100644 linked_queue.h diff --git a/linked_queue.h b/linked_queue.h new file mode 100644 index 0000000..4c1297a --- /dev/null +++ b/linked_queue.h @@ -0,0 +1,97 @@ +#ifndef _UTIL_LINKED_QUEUE_H +#define _UTIL_LINKED_QUEUE_H +#include +#include +#include + +template +struct LinkedQueueNode { + T d; + struct LinkedQueueNode* next; +}; + +template +struct LinkedQueue { + struct LinkedQueueNode* front; + struct LinkedQueueNode* rear; +}; + +template +size_t linked_queue_length(struct LinkedQueue& queue) { + if (!queue.front) return 0; + struct LinkedQueueNode* node = queue.front; + size_t i = 1; + while (node->next) { + node = node->next; + i++; + } + return i; +} + +template +void free_linked_queue(struct LinkedQueue& queue, std::function free_func = std::function()) { + if (!queue.front) return; + struct LinkedQueueNode* node = queue.front, *tmp = queue.front; + do { + tmp = node; + node = node->next; + if (free_func) { + free_func(tmp->d); + } + free(tmp); + } while (node); + queue.front = nullptr; + queue.rear = nullptr; +} + +template +inline void free_linked_queue(struct LinkedQueue& queue, F free_func) { + free_linked_queue(queue, std::function(free_func)); +} + +template +bool linked_queue_push(struct LinkedQueue& queue, T data) { + struct LinkedQueueNode* node = (struct LinkedQueueNode*)malloc(sizeof(struct LinkedQueueNode)); + if (!node) { + return false; + } + node->d = data; + node->next = nullptr; + if (queue.rear) { + queue.rear->next = node; + } else { + queue.front = node; + } + queue.rear = node; + return true; +} + +template +bool linked_queue_pop(struct LinkedQueue& queue, T& data) { + if (!queue.front) return false; + data = queue.front->d; + struct LinkedQueueNode* tmp = queue.front; + if (!tmp->next) { + queue.rear = nullptr; + } + queue.front = tmp->next; + free(tmp); + return true; +} + +template +void linked_queue_iter(struct LinkedQueue& queue, std::function callback, Args... args) { + if (!queue.front || !callback) return; + struct LinkedQueueNode* node = queue.front; + do { + callback(node->d, args...); + node = node->next; + } while (node); +} + +template +inline void linked_queue_iter(struct LinkedQueue& queue, F callback, Args... args) { + linked_queue_iter(queue, std::function(callback), args...); +} + +#endif diff --git a/test/queue_test.cpp b/test/queue_test.cpp index 2ba430d..30a65e6 100644 --- a/test/queue_test.cpp +++ b/test/queue_test.cpp @@ -1,5 +1,6 @@ #include "gtest/gtest.h" #include "circular_queue.h" +#include "linked_queue.h" #include TEST(Queue_Test, CircularQueue1) { @@ -81,3 +82,26 @@ TEST(Queue_Test, CircularQueue2) { EXPECT_EQ(text, "2,3,4,5"); free_circular_queue(queue); } + +TEST(Queue_Test, LinkedQueue1) { + struct LinkedQueue queue; + queue.front = nullptr; + queue.rear = nullptr; + EXPECT_EQ(linked_queue_push(queue, 3), true); + EXPECT_EQ(linked_queue_push(queue, 4), true); + EXPECT_EQ(linked_queue_push(queue, 9), true); + int v; + EXPECT_EQ(linked_queue_pop(queue, v), true); + EXPECT_EQ(v, 3); + EXPECT_EQ(linked_queue_push(queue, 7), true); + EXPECT_EQ(linked_queue_length(queue), 3); + std::string text = ""; + linked_queue_iter(queue, [&text](int ele) { + if (!text.empty()) { + text += ","; + } + text += std::to_string(ele); + }); + EXPECT_EQ(text, "4,9,7"); + free_linked_queue(queue); +}