Add LinkedQueue

This commit is contained in:
2024-06-20 19:40:12 +08:00
parent 6f77322eb4
commit 7d466865f5
2 changed files with 121 additions and 0 deletions

97
linked_queue.h Normal file
View File

@@ -0,0 +1,97 @@
#ifndef _UTIL_LINKED_QUEUE_H
#define _UTIL_LINKED_QUEUE_H
#include <functional>
#include <stddef.h>
#include <malloc.h>
template <typename T>
struct LinkedQueueNode {
T d;
struct LinkedQueueNode* next;
};
template <typename T>
struct LinkedQueue {
struct LinkedQueueNode<T>* front;
struct LinkedQueueNode<T>* rear;
};
template <typename T>
size_t linked_queue_length(struct LinkedQueue<T>& queue) {
if (!queue.front) return 0;
struct LinkedQueueNode<T>* node = queue.front;
size_t i = 1;
while (node->next) {
node = node->next;
i++;
}
return i;
}
template <typename T>
void free_linked_queue(struct LinkedQueue<T>& queue, std::function<void(T)> free_func = std::function<void(T)>()) {
if (!queue.front) return;
struct LinkedQueueNode<T>* 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 <typename T, class F>
inline void free_linked_queue(struct LinkedQueue<T>& queue, F free_func) {
free_linked_queue(queue, std::function<void(T)>(free_func));
}
template <typename T>
bool linked_queue_push(struct LinkedQueue<T>& queue, T data) {
struct LinkedQueueNode<T>* node = (struct LinkedQueueNode<T>*)malloc(sizeof(struct LinkedQueueNode<T>));
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 <typename T>
bool linked_queue_pop(struct LinkedQueue<T>& queue, T& data) {
if (!queue.front) return false;
data = queue.front->d;
struct LinkedQueueNode<T>* tmp = queue.front;
if (!tmp->next) {
queue.rear = nullptr;
}
queue.front = tmp->next;
free(tmp);
return true;
}
template <typename T, typename ...Args>
void linked_queue_iter(struct LinkedQueue<T>& queue, std::function<void(T, Args...)> callback, Args... args) {
if (!queue.front || !callback) return;
struct LinkedQueueNode<T>* node = queue.front;
do {
callback(node->d, args...);
node = node->next;
} while (node);
}
template <typename T, class F, typename ...Args>
inline void linked_queue_iter(struct LinkedQueue<T>& queue, F callback, Args... args) {
linked_queue_iter(queue, std::function<void(T, Args...)>(callback), args...);
}
#endif

View File

@@ -1,5 +1,6 @@
#include "gtest/gtest.h"
#include "circular_queue.h"
#include "linked_queue.h"
#include <string>
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<int> 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);
}