C言語による循環キューの実装

循環キューとは

循環キューは線形データ構造の一種で、FIFO(先入れ先出し)原則に基づく操作を提供します。通常のキューと異なり、末尾要素が先頭要素に接続されて環状構造を形成するため、リングバッファとも呼ばれます。

循環キューの利点

従来のキューでは領域が満杯になると追加操作が不可能でしたが、循環キューでは先頭側の未使用領域を再利用できるため、メモリ効率が向上します。

データ構造の定義

typedef struct {
    int read_pos;   // 読取位置
    int write_pos;  // 書込位置
    int buffer_size; // バッファ容量
    int* data;      // データ格納配列
} CircularQueue;

基本操作の実装

初期化処理

CircularQueue* create_queue(int capacity) {
    CircularQueue* q = malloc(sizeof(CircularQueue));
    q->buffer_size = capacity + 1;
    q->read_pos = q->write_pos = 0;
    q->data = malloc(sizeof(int) * q->buffer_size);
    return q;
}

空状態の判定

bool is_empty(CircularQueue* q) {
    return q->write_pos == q->read_pos;
}

満杯状態の判定

bool is_full(CircularQueue* q) {
    return (q->write_pos + 1) % q->buffer_size == q->read_pos;
}

要素の追加

bool enqueue(CircularQueue* q, int value) {
    if (is_full(q)) return false;
    
    q->data[q->write_pos] = value;
    q->write_pos = (q->write_pos + 1) % q->buffer_size;
    return true;
}

要素の取り出し

bool dequeue(CircularQueue* q) {
    if (is_empty(q)) return false;
    
    q->read_pos = (q->read_pos + 1) % q->buffer_size;
    return true;
}

先頭要素の参照

int get_front(CircularQueue* q) {
    return is_empty(q) ? -1 : q->data[q->read_pos];
}

末尾要素の参照

int get_rear(CircularQueue* q) {
    if (is_empty(q)) return -1;
    
    int last_pos = (q->write_pos - 1 + q->buffer_size) % q->buffer_size;
    return q->data[last_pos];
}

メモリ解放

void free_queue(CircularQueue* q) {
    free(q->data);
    free(q);
}

使用例

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

int main() {
    CircularQueue* q = create_queue(3);
    
    enqueue(q, 10);
    enqueue(q, 20);
    enqueue(q, 30);
    
    printf("先頭要素: %d\n", get_front(q));
    printf("末尾要素: %d\n", get_rear(q));
    
    dequeue(q);
    enqueue(q, 40);
    
    printf("更新後の末尾: %d\n", get_rear(q));
    
    free_queue(q);
    return 0;
}

タグ: C言語 データ構造 循環キュー リングバッファ アルゴリズム

7月1日 00:16 投稿