定义

队列是限制在两端进行插入操作和删除操作的线性表

  • 对尾:允许进行存入操作的一端
  • 对头:允许进行删除操作的一端
  • 空队:当线性表当中没有元素时
  • 特点:先进先出(FIFO)
  • 双端队列:两端多可以入队出队

顺序队列(循环队列)

  • front:指向对头元素的位置
  • rear;指向对尾元素的下一个位置
  • 空队:front = rear = 0
  • 满队:(sq->rear + 1) % N == sq->front(满队元素个数要比这个的数组数组空间少1)
  • 实现循环队列:取余

头文件:sequeue.h

typedef int datatype;

#define N 128

typedef struct _stSequeue{
    datatype data[N];
    int front;
    int rear;
}stSequeue;

stSequeue *QueueCreate();
int EnQueue(stSequeue *sq, datatype x);
datatype DeQueue(stSequeue *sq);
int EmptyQueue(stSequeue *sq);
int FullQueue(stSequeue *sq);
int ClearQueue(stSequeue *sq);
stSequeue* FreeSqueue(stSequeue *sq);

队列.文件:sequeue.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "sequeue.h"

stSequeue *QueueCreate(){
    stSequeue *sq = (stSequeue *)malloc(sizeof(stSequeue));
    if(sq == NULL){
        printf("malloc failed!\n");
        return NULL;
    }
    memset(sq->data,0,sizeof(sq->data));
    sq->front = sq->rear = 0;
    return sq;
}
int EnQueue(stSequeue *sq, datatype x){    
    if(sq == NULL){
        printf("sp is NULL\n");
        return -1;
    }
    if((sq->rear + 1) % N == sq->front){
        printf("sequeue if full\n");
        return -1;
    }

    sq->data[sq->rear] = x;
    sq->rear = (sq->rear + 1) % N;

    return 0;
}
datatype DeQueue(stSequeue *sq){
    if(sq == NULL){
        printf("sq is NULL\n");
        return -1;
    }

    datatype temp;

    temp = sq->data[sq->front];
    sq->front = (sq->front + 1) % N;

    return temp;
}
int EmptyQueue(stSequeue *sq){
    if(sq == NULL){
        printf("sq is NULL\n");
        return -1;
    }
    if(sq->rear == sq->front){
        printf("sequeue if empty\n");
        return 1;
    }
    return 0;
}
int FullQueue(stSequeue *sq){    
    if(sq == NULL){
        printf("sq is NULL\n");
        return -1;
    }
    if((sq->rear + 1) % N == sq->front){
        printf("sequeue if full\n");
        return 1;
    }
    return 0;
}
int ClearQueue(stSequeue *sq){
    if(sq == NULL){
        printf("sq is NULL\n");
        return -1;
    }
    memset(sq->data,0,sizeof(sq->data));
    sq->front = sq->rear = 0;

    return 0;
}
stSequeue* FreeSqueue(stSequeue *sq){
    if(sq == NULL){
        printf("sq is NULL\n");
        return NULL;
    }
    free(sq);
    sq = NULL;
    return NULL;
}

主函数:

#include <stdio.h>
#include <stdlib.h>
#include "sequeue.h"

int main(){

    stSequeue *sq;
    sq = QueueCreate();
    if(sq == NULL){
        printf("sq is NULL\n");
    }

    EnQueue(sq,10);
    EnQueue(sq,100);
    EnQueue(sq,1000);
    EnQueue(sq,10000);

    while(!EmptyQueue(sq)){
        printf("datatype:%d\n",DeQueue(sq));
    }

    sq = FreeSqueue(sq);

    printf("start:\n");
    return 0;
}

结果:

题目

1、顺序队列为什么要采用循环的方式?

随着队列元素不断地入队出队,如果队头一直不前移一定会出现队头队尾指向同一位置,那样我们的队列就消失了,当然可以采用队列元素出队列后,剩余元素前移一个位置,但是这样的操作增加了代码冗余和时间复杂度,所以顺序队列采用循环的方式。

2、循环队列如何判断空和满?

满队元素个数比整个队列的存储空间数目少1,空队的头和为指针指向同一个数。