1、顺序队列的原理
队列是限制在两端进行插入操作和删除操作的线性表
允许进行存入操作的一端称为“队尾”
允许进行删除操作的一端称为“队头”
当线性表中没有元素时,称为“空队”
特点:先进先出(FIFO)
双端队列
2、顺序队列的实现
声明结构体
typedef int datatype;
#define N 128
typedef struct {
datatype data[N];
int front;
int rear;
}sequeue;
2.1 创建队列
sequeue * queue_create() {
sequeue *sq;
if ((sq = (sequeue *)malloc(sizeof(sequeue))) == NULL) {
printf("malloc failed\n");
return NULL;
}
memset(sq->data, 0, sizeof(sq->data));
sq->front = sq->rear = 0;
return sq;
}
2.2 入队
int enqueue(sequeue *sq, datatype x) {
if (sq == NULL) {
printf("sq is NULL\n");
return -1;
}
if ((sq->rear + 1) % N == sq->front) {
printf("sequeue is full\n");
return -1;
}
sq->data[sq->rear] = x;
sq->rear = (sq->rear + 1) % N;
return 0;
}
2.3 出队
datatype dequeue(sequeue *sq) {
datatype ret;
ret = sq->data[sq->front];
sq->front = (sq->front + 1) % N;
return ret;
}
2.4 空队
int queue_empty(sequeue *sq) {
if (sq == NULL) {
printf("sq is NULL\n");
return -1;
}
return (sq->front == sq->rear ? 1 : 0);
}
2.5 满队
int queue_full(sequeue *sq) {
if (sq == NULL) {
printf("sq is NULL\n");
return -1;
}
if ((sq->rear + 1) % N == sq->front) {
return 1;
}
else {
return 0;
}
}
2.6 清空队列
int queue_clear(sequeue *sq) {
if (sq == NULL) {
printf("sq is NULL\n");
return -1;
}
sq->front = sq->rear = 0;
return 0;
}
2.7 队列释放
sequeue * queue_free(sequeue *sq) {
if (sq == NULL) {
printf("sq is NULL\n");
return NULL;
}
free(sq);
sq = NULL;
return NULL;
}
3、链式队列的原理![在这里插入图片描述](https://img-blog.csdnimg.cn/d256fe08aff5470e827eab30f69f857f.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5LuZ5YWr5ZOl,size_20,color_FFFFFF,t_70,g_se,x_16)
4、链式队列的实现
声明结构体
typedef int datatype;
typedef struct node {
datatype data;
struct node *next;
}listnode , *linklist;
typedef struct {
linklist front;
linklist rear;
}linkqueue;
4.1 创建队列
linkqueue * queue_create() {
linkqueue *lq;
if ((lq = (linkqueue *)malloc(sizeof(linkqueue))) == NULL) {
printf("malloc linkqueue failed\n");
return NULL;
}
lq->front = lq->rear = (linklist)malloc(sizeof(listnode));
if (lq->front == NULL) {
printf("malloc node failed\n");
return NULL;
}
lq->front->data = 0;
lq->front->next = NULL;
return lq;
}
4.2 入队
int enqueue(linkqueue *lq, datatype x) {
linklist p;
if (lq == NULL) {
printf("lq is NULL\n");
return -1;
}
if ((p = (linklist)malloc(sizeof(listnode))) == NULL) {
printf("malloc node failed\n");
return -1;
}
p->data = x;
p->next = NULL;
lq->rear->next = p;
lq->rear = p;
return 0;
}
4.3 出队
datatype dequeue(linkqueue *lq) {
linklist p;
if (lq == NULL) {
printf("lq is NULL\n");
return -1;
}
p = lq->front;
lq->front = p->next;
free(p);
p = NULL;
return (lq->front->data);
}
4.4 空队
int queue_empty(linkqueue *lq) {
if (lq == NULL) {
printf("lq is NULL\n");
return -1;
}
return (lq->front == lq->rear ? 1 : 0);
}
4.5 清空队列
int queue_clear(linkqueue *lq) {
linklist p;
if (lq == NULL) {
printf("lq is NULL\n");
return -1;
}
while (lq->front->next) {
p = lq->front;
lq->front = p->next;
printf("clear free:%d\n", p->data);
free(p);
p = NULL;
}
return 0;
}
4.6 释放队列
linkqueue * queue_free(linkqueue *lq) {
linklist p;
if (lq == NULL) {
printf("lq is NULL\n");
return NULL;
}
while (lq->front) {
p = lq->front;
lq->front = p->next;
printf("free:%d\n", p->data);
free(p);
}
free(lq);
lq = NULL;
return NULL;
}
5、栈和队列的应用—球钟问题
#include <stdio.h>
#include "linkqueue.h"
#include "sqstack.h"
int check(linkqueue * lq);
int main(int argc, const char *argv[])
{
linkqueue *lq;
sqstack *s_hour, *s_five, *s_min;
int value;
int i, min = 0;
if ((lq = queue_create()) == NULL) {
return -1;
}
for (i = 1; i <= 27; i++) {
enqueue(lq, i);
}
if ((s_hour = stack_create(11)) == NULL) {
return -1;
}
if ((s_five = stack_create(11)) == NULL) {
return -1;
}
if ((s_min = stack_create(4)) == NULL) {
return -1;
}
while (1) {
min++;
if (!queue_empty(lq)) {
value = dequeue(lq);
if (!stack_full(s_min)) {
stack_push(s_min, value);
} else {
while (!stack_empty(s_min)) {
enqueue(lq, stack_pop(s_min));
}
if (!stack_full(s_five)) {
stack_push(s_five, value);
} else {
while (!stack_empty(s_five)) {
enqueue(lq, stack_pop(s_five));
}
if (!stack_full(s_hour)) {
stack_push(s_hour, value);
} else {
while (!stack_empty(s_hour)) {
enqueue(lq, stack_pop(s_hour));
}
enqueue(lq, value);
//0:0
if (check(lq) == 1) {//检查队列是否升序
break;
}
}
}
}
}
}
printf("total:%d\n", min);
printf("dequeue:");
while (!queue_empty(lq))
printf("%d ", dequeue(lq));
puts("");
return 0;
}
int check(linkqueue * lq) {
linklist p;
if (lq == NULL) {
printf("lq is NULL\n");
return -1;
}
p = lq->front->next;
while (p && p->next) {
if (p->data < p->next->data) {
p = p->next;
} else {
return 0;
}
}
return 1;
}