ringbuffer.c
unknown
c_cpp
8 days ago
4.4 kB
68
Indexable
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
// Node structure for the linked list
typedef struct Node {
int data;
struct Node* next;
} Node;
// Ring buffer structure
typedef struct {
Node* head; // Points to the oldest element (front)
Node* tail; // Points to the newest element (back)
int size; // Current number of elements
int capacity; // Maximum capacity of the buffer
} RingBuffer;
// Create a new ring buffer with fixed capacity
RingBuffer* createRingBuffer(int capacity) {
if (capacity <= 0) {
return NULL;
}
RingBuffer* rb = (RingBuffer*)malloc(sizeof(RingBuffer));
if (!rb) {
return NULL;
}
rb->head = NULL;
rb->tail = NULL;
rb->size = 0;
rb->capacity = capacity;
return rb;
}
// Check if the buffer is empty
bool isEmpty(RingBuffer* rb) {
return rb->size == 0;
}
// Check if the buffer is full
bool isFull(RingBuffer* rb) {
return rb->size == rb->capacity;
}
// Add an element to the buffer (overwrites oldest if full)
bool push(RingBuffer* rb, int value) {
if (!rb) {
return false;
}
Node* newNode = (Node*)malloc(sizeof(Node));
if (!newNode) {
return false;
}
newNode->data = value;
newNode->next = NULL;
// If buffer is empty
if (isEmpty(rb)) {
rb->head = newNode;
rb->tail = newNode;
rb->size = 1;
return true;
}
// If buffer is full, remove the oldest element
if (isFull(rb)) {
Node* oldHead = rb->head;
rb->head = rb->head->next;
free(oldHead);
rb->size--;
}
// Add new element to the end
rb->tail->next = newNode;
rb->tail = newNode;
rb->size++;
return true;
}
// Remove and return the oldest element
bool pop(RingBuffer* rb, int* value) {
if (!rb || isEmpty(rb)) {
return false;
}
Node* oldHead = rb->head;
*value = oldHead->data;
rb->head = rb->head->next;
free(oldHead);
rb->size--;
// If buffer becomes empty, reset tail
if (isEmpty(rb)) {
rb->tail = NULL;
}
return true;
}
// Peek at the oldest element without removing it
bool peek(RingBuffer* rb, int* value) {
if (!rb || isEmpty(rb)) {
return false;
}
*value = rb->head->data;
return true;
}
// Get the current size of the buffer
int getSize(RingBuffer* rb) {
return rb ? rb->size : 0;
}
// Get the capacity of the buffer
int getCapacity(RingBuffer* rb) {
return rb ? rb->capacity : 0;
}
// Display all elements in the buffer
void display(RingBuffer* rb) {
if (!rb || isEmpty(rb)) {
printf("Buffer is empty\n");
return;
}
printf("Buffer contents (oldest to newest): ");
Node* current = rb->head;
while (current) {
printf("%d ", current->data);
current = current->next;
}
printf("\n");
}
// Clear all elements from the buffer
void clear(RingBuffer* rb) {
if (!rb) {
return;
}
Node* current = rb->head;
while (current) {
Node* temp = current;
current = current->next;
free(temp);
}
rb->head = NULL;
rb->tail = NULL;
rb->size = 0;
}
// Free the ring buffer
void destroyRingBuffer(RingBuffer* rb) {
if (rb) {
clear(rb);
free(rb);
}
}
// Example usage
int main() {
// Create a ring buffer with capacity 5
RingBuffer* rb = createRingBuffer(5);
printf("Created ring buffer with capacity: %d\n\n", getCapacity(rb));
// Push some elements
printf("Pushing elements 1, 2, 3, 4, 5:\n");
for (int i = 1; i <= 5; i++) {
push(rb, i);
printf("Pushed: %d, Size: %d\n", i, getSize(rb));
}
display(rb);
printf("\nPushing elements 6 and 7 (should overwrite oldest):\n");
push(rb, 6);
printf("Pushed: 6, Size: %d\n", getSize(rb));
push(rb, 7);
printf("Pushed: 7, Size: %d\n", getSize(rb));
display(rb);
printf("\nPopping elements:\n");
int value;
while (pop(rb, &value)) {
printf("Popped: %d, Size: %d\n", value, getSize(rb));
}
printf("\nTesting with empty buffer:\n");
display(rb);
// Clean up
destroyRingBuffer(rb);
return 0;
}Editor is loading...
Leave a Comment