C语言中环形队列的应用,请举例
时间: 2023-08-22 22:03:28 浏览: 126
环形队列是一种特殊的队列数据结构,它可以利用数组来实现循环存储。在C语言中,环形队列常用于需要循环取出数据的场景,例如音乐播放器中的缓冲区、生产者消费者模型中的消息队列等。
下面以生产者消费者模型为例,介绍一下如何使用环形队列:
1. 定义环形队列的结构体,包含队列的大小、队头和队尾指针、队列元素数组等成员变量。
```
#define QUEUE_SIZE 10
typedef struct {
int data[QUEUE_SIZE];
int front; // 队头指针
int rear; // 队尾指针
} CircularQueue;
```
2. 初始化队列,将队头和队尾指针都设置为0。
```
void initQueue(CircularQueue *queue) {
queue->front = 0;
queue->rear = 0;
}
```
3. 实现入队操作,将元素插入到队尾,并更新队尾指针。如果队列已满,则返回-1表示插入失败。
```
int enqueue(CircularQueue *queue, int value) {
int nextRear = (queue->rear + 1) % QUEUE_SIZE; // 计算下一个队尾指针
if (nextRear == queue->front) { // 队列已满
return -1;
}
queue->data[queue->rear] = value;
queue->rear = nextRear;
return 0;
}
```
4. 实现出队操作,从队头取出元素,并更新队头指针。如果队列为空,则返回-1表示取出失败。
```
int dequeue(CircularQueue *queue) {
if (queue->front == queue->rear) { // 队列为空
return -1;
}
int value = queue->data[queue->front];
queue->front = (queue->front + 1) % QUEUE_SIZE; // 更新队头指针
return value;
}
```
5. 在生产者消费者模型中,生产者向队列中插入数据,消费者从队列中取出数据。生产者和消费者都需要持有队列的指针。
```
void *producer(void *arg) {
CircularQueue *queue = (CircularQueue *)arg;
for (int i = 0; i < 100; i++) {
int ret = enqueue(queue, i);
if (ret == -1) {
printf("producer: queue is full\n");
} else {
printf("producer: enqueue %d\n", i);
}
}
pthread_exit(NULL);
}
void *consumer(void *arg) {
CircularQueue *queue = (CircularQueue *)arg;
for (int i = 0; i < 100; i++) {
int value = dequeue(queue);
if (value == -1) {
printf("consumer: queue is empty\n");
} else {
printf("consumer: dequeue %d\n", value);
}
}
pthread_exit(NULL);
}
int main() {
CircularQueue queue;
initQueue(&queue);
pthread_t producerThread, consumerThread;
pthread_create(&producerThread, NULL, producer, &queue);
pthread_create(&consumerThread, NULL, consumer, &queue);
pthread_join(producerThread, NULL);
pthread_join(consumerThread, NULL);
return 0;
}
```
上面的代码中,生产者往队列中插入数据,消费者从队列中取出数据,当队列已满时,生产者会输出"producer: queue is full",当队列为空时,消费者会输出"consumer: queue is empty"。通过使用环形队列,我们可以实现循环存储,并且不需要移动元素,提高了队列操作的效率。
阅读全文