队列--循环buffer

队列是一种“先进先出的数据结构”,可分为静态队列和链式队列。静态队列一般使用数组实现,数组需要预先定义内存大小,为了避免内存浪费,一般使用循环队列。著名的生产者与消费者理论,一个写数据,一个读数据,使得内存可以重复利用。接下来讲述循环队列的原理以及实现代码。

分析下面数组的实现过程,假设数组的大小为5

该方法存在一个问题: 当rear和front到数组下标最后一个元素后,再写入或读出该如何操作?——答案是我们将它抽象为环形

当tail为4的时候,实际上已经到数据5这个位置了,再写就会导致溢出,因此我们tail = (tail+1)%buf_size,结果为0,因此就回到了0。

空时条件front==tail,满时也为front==tail, 如何判断循环buffer是否为空或满?

解决办法:尾部更新 tail = (tail+1)%rb_size;

空一个存储单位不存储数据,这样:

  • 空条件: rear==front

  • 满条件: (rear+1) % rb_size == front

  • buffer中数据大小: (rear+rb_size-front)%rb_size

具体实现参考链接:队列的实现(1):循环队列的实现_(1)实现一个循环队列。向队列中插入自己名字对应的拼音(一个字母对应一个元素,),-CSDN博客

我是用了一个变量size来实时监测数组里元素的大小,用上面的方法把判断满还是空换掉就行。

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

#define SIZE 8 // 缓冲区大小

typedef struct ring_buffer_s {
        int head;
        int tail;
        int size;//(tail+SIZE-head)%SIZE
        char buffer[SIZE];
}ring_buffer_t;

void ringbuffer_init(ring_buffer_t *rb);
int ringbuffer_read(ring_buffer_t *rb, int *data);
int ringbuffer_write(ring_buffer_t *rb, int data);
bool ringbuffer_empty(ring_buffer_t *rb); 
bool ringbuffer_full(ring_buffer_t *rb);
void ringbuffer_print(ring_buffer_t *rb);

int main (int argc, char **argv)
{
        ring_buffer_t   rb;
        int             i;
        int             data;

        ringbuffer_init(&rb);

        for( i=0; i<SIZE; i++)
        {
                if( ringbuffer_write(&rb, i) == 1 )
                {
                        printf("write %d success\n",i);
                }
                printf("buffer is full,cannot write %d\n",i);
        }

        ringbuffer_print(&rb);

        for( i=0; i<5; i++)
        {
                if (ringbuffer_read(&rb, &data))
                {
                        printf("Read %d from buffer\n", data);
                }
                else
                printf("buffer is empty\n");
        }

        ringbuffer_print(&rb);

        return 0;
} 

void ringbuffer_init(ring_buffer_t *rb)
{
        rb->head = 0;
        rb->tail = 0;
        rb->size = 0;
}

bool ringbuffer_full(ring_buffer_t *rb) 
{
        return rb->size == SIZE;
    //(rb->tail+1)%SIZE == head;
}

bool ringbuffer_empty(ring_buffer_t *rb) 
{
   return rb->size == 0;
    //tail == head
}

int ringbuffer_write(ring_buffer_t *rb, int data)
{
        if(ringbuffer_full(rb))
        {
                return -1;
        }
        rb->buffer[rb->tail] = data;
        rb->tail = (rb->tail+1)%SIZE;
        rb->size++;
        return 1;
}

int ringbuffer_read(ring_buffer_t *rb, int *data)
{
        if( ringbuffer_empty(rb) )
                return -1;
        *data = rb->buffer[rb->head];
        rb->head = (rb->head+1)%SIZE;
        rb->size--;
        return 1;
}

void ringbuffer_print(ring_buffer_t *rb)
{
        int     i = rb->head;
        int     count = rb->size;

        while( count > 0 )
        {
                printf("%d",rb->buffer[i]);
                i = (i+1)%SIZE;
                count--;
        }
        printf("\n");
}
  
  • 18
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我可以帮你实现char buffer的两个队列循环。对于这个问题,我们可以使用两个循环队列来实现缓存的读写操作。 以下是一个简单的实现示例: ```c++ #include <iostream> #define MAX_SIZE 10 using namespace std; class CharBuffer { private: char data[MAX_SIZE]; int front1, rear1, front2, rear2; public: CharBuffer() { front1 = rear1 = front2 = rear2 = -1; } bool isEmpty1() { return front1 == -1 && rear1 == -1; } bool isFull1() { return (rear1+1)%MAX_SIZE == front1; } bool isEmpty2() { return front2 == -1 && rear2 == -1; } bool isFull2() { return (rear2+1)%MAX_SIZE == front2; } void enqueue1(char c) { if (isEmpty1()) { front1 = rear1 = 0; } else if (isFull1()) { cout << "Queue 1 is full!" << endl; return; } else { rear1 = (rear1+1) % MAX_SIZE; } data[rear1] = c; } char dequeue1() { if (isEmpty1()) { cout << "Queue 1 is empty!" << endl; return '\0'; } char c = data[front1]; if (front1 == rear1) { front1 = rear1 = -1; } else { front1 = (front1+1) % MAX_SIZE; } return c; } void enqueue2(char c) { if (isEmpty2()) { front2 = rear2 = 0; } else if (isFull2()) { cout << "Queue 2 is full!" << endl; return; } else { rear2 = (rear2+1) % MAX_SIZE; } data[rear2] = c; } char dequeue2() { if (isEmpty2()) { cout << "Queue 2 is empty!" << endl; return '\0'; } char c = data[front2]; if (front2 == rear2) { front2 = rear2 = -1; } else { front2 = (front2+1) % MAX_SIZE; } return c; } }; int main() { CharBuffer buffer; buffer.enqueue1('A'); buffer.enqueue1('B'); buffer.enqueue1('C'); buffer.enqueue2('1'); buffer.enqueue2('2'); buffer.enqueue2('3'); cout << "Dequeuing from Queue 1: " << buffer.dequeue1() << endl; cout << "Dequeuing from Queue 1: " << buffer.dequeue1() << endl; cout << "Dequeuing from Queue 2: " << buffer.dequeue2() << endl; cout << "Dequeuing from Queue 2: " << buffer.dequeue2() << endl; return 0; } ``` 在这个示例中,我们使用了一个CharBuffer类来实现char buffer的两个队列循环。CharBuffer类中包含了两个循环队列,分别用于存储数据。我们在enqueue1()和dequeue1()方法中实现了对Queue 1的读写操作,在enqueue2()和dequeue2()方法中实现了对Queue 2的读写操作。 在main()函数中,我们向Queue 1和Queue 2中添加了3个字符元素,然后依次从Queue 1和Queue 2中取出了两个元素。 希望这个示例可以帮助你实现char buffer的两个队列循环。如果你还有其他问题,请随时问我。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值