一、队列概述
队列是一个特殊的线性表,不能在线性表的中间位置进行操作,只能在线性表的两端进行操作
1.队头(front):线性表的表头,数据的删除端实现数据的删除操作,称数据元素的出队。
2.队尾(rear):线性表的表尾,数据的插入端实现数据的插入操作,称数据元素的入队。
队列的特性:先进先出
二、队列的顺序存储
顺序队列的存储空间:
1.顺序队列元素在操作之前,需要实现空间的开辟,开辟的空间大小固定;
2.在操作过程中,由于入队和出队都会是元素存储位置序号的递增,序号递增到空间最大序号值,最终可存储数据的个数有限;
3.每一个存储位置只能实现一个数据元素的入队和出队操作,空间只会使用一次,不会再次使用,会导致空间利用率较低。
顺序队列定义
typedef int data_t; //队列中数据元素的类型
struct sqqueue{
data_t *data; //动态开辟的首元素地址
int nmenmb; //空间中可存储元素的个数
int front;// 队头元素存储序号标签
int rear; //队尾元素存储序号标签
}sqqueue_t;
三、顺序循环队列
顺序循环队列实质是对顺序队列的优化,在遍历到空间最大的序号时,序号回到0开始继续向后办理。
循序队列的构建:
实质是创建连续的顺序存储空间,在访问时构建循环访问;
入队访问:队尾元素rear序号操作,rear = (rear+1)% nmemb;
出队访问:队头元素front序号操作,front = (front+1)% nmemb;
队尾rear和队头front初始值规定:
①front指向队头元素的前一个位置,rear指向队尾元素所在位置;
②front指向队头元素所在位置,rear指向队尾的下一个位置。
队为空的条件:
rear == front
队为满的条件:
按规定也为rear == front ,为了区分,队为满的元素个数=nmemb-1;
若采用②规定:
front和rear的默认初始值设为:front = 0;rear = 0;
队为空的条件还是:rear == front;
队为满的条件,需要牺牲一个空间来区别队列为空还是满:
1)rear > front ==>front == (rear+1)%nmemb;
2) rear < front ==>front ==raer + 1 <=> front == (rear+1)%nmemb;
综上:队满条件: front == (rear+1)%nmemb
四、相关操作
头文件:common.h
#ifndef _COMMON_H_
#define _COMMON_H_
typedef int data_t;
typedef struct queue{
data_t *data;
int nmemb;
int front;
int rear;
} sqqueue_t;
sqqueue_t *CreateSqQueue(int mynmemb);//初始化
int EnSqQueue(sqqueue_t *queue,data_t mydata);//入队
int GetSqQueue(sqqueue_t *queue,data_t *mydata);//查看对头元素
int DeSqQueue(sqqueue_t *queue);//出队
#endif
函数实现: sqqueue.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "common.h"
sqqueue_t *CreateSqQueue(int mynmemb)//初始化
{
sqqueue_t *queue = malloc(sizeof(sqqueue_t));
if(queue == NULL)
return NULL;
queue->data = calloc(mynmemb,sizeof(data_t));
if(queue->data == NULL){
free(queue);
return NULL;
}
queue->nmemb = mynmemb;
queue->front = 0;
queue->rear = 0;
return queue;
}
int EnSqQueue(sqqueue_t *queue,data_t mydata)//入队
{
//判断队满
if(queue->front == (queue->rear+1)%queue->nmemb)
return -1;
//放数据
queue->data[queue->rear] = mydata;
queue->rear = (queue->rear+1)%queue->nmemb;
return 0;
}
int GetSqQueue(sqqueue_t *queue,data_t *mydata)//查看对头元素
{
//判断是否为空
if(queue->front == queue->rear)
return-1;
*mydata = queue->data[queue->front];
return 0;
}
int DeSqQueue(sqqueue_t *queue)//出队
{
//判断是否为空
if(queue->front == queue->rear)
return -1;
queue->front = (queue->front+1)%queue->nmemb;
return 0;
}
主函数调用:app.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "common.h"
int main()
{
int i;
sqqueue_t *queue;
data_t mydata;
queue = CreateSqQueue(10);
if (queue == NULL)
return -1;
i = 20;
while(i) {
if (EnSqQueue(queue, i--) == -1) {
printf("%d En Fail\n", i);
}
}
while(GetSqQueue(queue, &mydata) == 0) {
printf("De : %d\n", mydata);
DeSqQueue(queue);
}
}