数据结构之C语言循环队列的数组实现

本文详细介绍了队列的概念,作为先进先出(FIFO)的数据结构,队列在打印机队列、网页爬虫、系统缓冲区等场景中有广泛应用。接着,通过C语言展示了如何使用数组实现队列,包括创建、入队、出队、判空、判满、遍历打印及销毁等操作,并特别提到了循环队列的概念以解决数组队列满的问题。最后,提供了一个完整的代码示例来演示队列操作的过程。
摘要由CSDN通过智能技术生成

一、队列模型

  • 队列是一种特殊的线性表,它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作。也可称为先进先出(FIFO)表
  • 队列的动画:http://liveexample.pearsoncmg.com/liang/animation/web/Queue.html
    在这里插入图片描述
  • 队列的应用
    – Printer Queue
    – Web Crawler
    – System Buffer
    – Any sequence maintained in a FIFO order

二、队列的数组实现

1. 队列的数据结构

typedef struct { 
  double *values;  // 可以为任意数据类型
  int front; 
  int rear; 
  int counter; // 队列中元素的数量
  int maxSize;  // 队列大小
} Queue;

2. 队列的创建

💡 这里我们初始化 rear = -1,则当我们入队第一个元素时 rear = 0,相对应于数组 A[0]

bool CreateQueue(Queue *queue, int size){
	if (size < 1){
		printf("Error: size should be positive.\n");
		return false;
	}
	queue->values = (double*)malloc(sizeof(double) * size);
	queue->front = 0;
	queue->rear = -1;
	queue->counter = 0;
	queue->maxSize = size;
	return true;
}

3. 入队和出队

  • 为了使一个元素X入队,我们让 counter 和 rear 加1。
    入队
  • 为了使一个元素X出队,我们让counter减 1,front 加1。
    出队

⚠️ 这种实现存在一个潜在的问题。经过 3 次入队后队列似乎是满了,因为 rear现在为 10,若下一次再入列就会是一个不存在的位置,但在这之前可能进行了几次出队的操作,这时队列中可能只有 1 个或 2 个元素。
💡 一个简单的解决方法使,当 front 或 rear 到达数组的尾端,他就又绕回开头。这叫做循环队列(circular queue)
循环队列

  • 入队
    入队
bool Enqueue(Queue *queue, double x){
	if (IsFull(queue)){
		return false;
	}
	// adds a new element with values x to the rear of the queue
	queue->rear = (queue->rear + 1) % queue->maxSize;
	queue->values[queue->rear] = x;
	queue->counter++;
	return true;
}
  • 出队
    出队
bool Dequeue(Queue *queue, double *x){
	if (IsEmpty(queue)){
		return false;
	}
	// removes an element from the front of the queue
	// passes the value of the front element to x
	*x = queue->values[queue->front];
	queue->front = (queue->front + 1) % queue->maxSize;
	queue->counter--;
	return true;
}

4. 其他基本操作

  • 判空和判满
bool IsEmpty(Queue *queue){
	return queue->counter == 0;
}

bool IsFull(Queue *queue){
	return queue->counter == queue->maxSize;
}
  • 历遍打印
void DisplayQueue(Queue *queue){
	if (IsEmpty(queue)){
		printf("The queue is empty!\n");
	}
	else{
		printf("front-->");
		int i=queue->front;
		int a=0;
		for(a = 0 ; a<queue->counter; a++){
			if (a<queue->counter-1){
				printf("%f\n\t", queue->values[(queue->front+a)%queue->maxSize]);
			}
			else{
				printf("%f", queue->values[(queue->front+a)%queue->maxSize]);
			}
		}
		printf("<--rear\n");
	}
}
  • 销毁
void DestroyQueue(Queue *queue){
	free(queue->values);
	queue->counter = 0;
	queue->front = 0;
	queue->rear = -1;
	queue->values = NULL;
}

5. 完整代码

  • queue.h
#include <stdbool.h>

typedef struct { 
  double *values;
  int front; 
  int rear; 
  int counter; 
  int maxSize;
} Queue;

bool CreateQueue(Queue *queue, int size);

bool IsEmpty(Queue *queue);

bool IsFull(Queue *queue);

bool Enqueue(Queue *queue, double x);

bool Dequeue(Queue *queue, double *x);

void DisplayQueue(Queue *queue);

void DestroyQueue(Queue *queue);
  • queue.c
#include <stdbool.h>
#include <stdlib.h>
#include <stdio.h>
#include "queue.h"

bool CreateQueue(Queue *queue, int size){
	if (size < 1){
		printf("Error: size should be positive.\n");
		return false;
	}
	queue->values = (double*)malloc(sizeof(double) * size);
	queue->front = 0;
	queue->rear = -1;
	queue->counter = 0;
	queue->maxSize = size;
	return true;
}

bool IsEmpty(Queue *queue){
	return queue->counter == 0;
}

bool IsFull(Queue *queue){
	return queue->counter == queue->maxSize;
}

bool Enqueue(Queue *queue, double x){
	if (IsFull(queue)){
		return false;
	}
	// adds a new element with values x to the rear of the queue
	queue->rear = (queue->rear + 1) % queue->maxSize;
	queue->values[queue->rear] = x;
	queue->counter++;
	return true;
}

bool Dequeue(Queue *queue, double *x){
	if (IsEmpty(queue)){
		return false;
	}
	// removes an element from the front of the queue
	// passes the value of the front element to x
	*x = queue->values[queue->front];
	queue->front = (queue->front + 1) % queue->maxSize;
	queue->counter--;
	return true;
}

void DisplayQueue(Queue *queue){
	if (IsEmpty(queue)){
		printf("The queue is empty!\n");
	}
	else{
		printf("front-->");
		int i=queue->front;
		int a=0;
		for(a = 0 ; a<queue->counter; a++){
			if (a<queue->counter-1){
				printf("%f\n\t", queue->values[(queue->front+a)%queue->maxSize]);
			}
			else{
				printf("%f", queue->values[(queue->front+a)%queue->maxSize]);
			}
		}
		printf("<--rear\n");
	}
}

void DestroyQueue(Queue *queue){
	free(queue->values);
	queue->counter = 0;
	queue->front = 0;
	queue->rear = -1;
	queue->values = NULL;
}
  • main.c
#include <stdio.h>
#include <stdbool.h>
#include "queue.h"

int main(void) {
	Queue queue;
	double value;
	CreateQueue(&queue, 5);
	puts("Enqueue 5 items.");
	for(int x = 0; x < 5; x++)
		Enqueue(&queue, x);
	puts("Now attempting to enqueue again...");
	Enqueue(&queue, 5.0);
	DisplayQueue(&queue);
	printf("\n");
	Dequeue(&queue, &value);
	printf("Retrieved element = %f\n", value);
	printf("\n");
	DisplayQueue(&queue);
	printf("\n");
	Enqueue(&queue, 7.0);
	DisplayQueue(&queue);
	printf("\n");
	DestroyQueue(&queue);
	return 0;
}
  • 结果显示
    Output

🚩 以上均为个人学习数据结构算法时的小笔记,如有错误请多多指正

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值