mirror of
https://github.com/lifegpc/c-utils.git
synced 2026-06-08 22:28:54 +08:00
Add LinkedQueue
This commit is contained in:
97
linked_queue.h
Normal file
97
linked_queue.h
Normal 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
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user