一、定义
队列(queue)是只允许在一端进行插入操作,而在另一端进行删除操作的线性表。
逻辑结构:线性结构
存储结构:顺序、链式
特点:先进先出(FIFO)
二、循环队列
普通的顺序队列会浪费已经存储过数据的空间,所以一般采用循环队列,即头尾相接的循环,利用除法取余运算(%)来实现。
其结构体为:
#defien N 64
typedef int data_t;
typedef struct seq_queue
{
data_t buf[N];
int rear;//队尾指针,指向最后一个元素的下一个位置
int front;//队头指针,指向出队元素下标
}Seq_queue;
队列基本操作的功能函数:
注:空队列:front==rear
满队列:(rear+1)%N == front
//队列中入对最大数为N-1,留一个空以区分空队列和满队列
/*===============================================
* 文件名称:seq_queue.c
* 创 建 者:xm
* 创建日期:2022年07月30日
* 描 述:循环队列-顺序表实现
================================================*/
#include "seq_queue.h"
//创建队列
Seq_queue *create_seq_queue()
{
Seq_queue *s=(Seq_queue *)malloc(sizeof(Seq_queue));
if(NULL==s)
{
printf("malloc error!\n");
return NULL;
}
memset(s->buf,0,sizeof(s->buf));
s->front=0;
s->rear=0;
return s;
}
//判满
int seq_queue_is_full(Seq_queue *s)
{
if((s->rear+1)%N == s->front)return 1;
else return 0;
}
//判空
int seq_queue_is_empty(Seq_queue *s)
{
if(s->rear == s->front) return 1;
else return 0;
}
//入队
void seq_queue_push(Seq_queue *s,data_t data)
{
if(seq_queue_is_full(s))
{
printf("queue is full\n");
return ;
}
s->buf[s->rear]=data;
s->rear=(s->rear+1)%N;
}
//出队
void seq_queue_pop(Seq_queue *s,data_t *data)
{
if(seq_queue_is_empty(s))
{
printf("queue is empty\n");
return ;
}
*data=s->buf[s->front];
s->front=(s->front+1)%N;
}
头文件:
/*===============================================
* 文件名称:seq_queue.h
* 创 建 者:xm
* 创建日期:2022年07月30日
* 描 述:
================================================*/
#ifndef _SEQQUEUE_
#define _SEQQUEUE_
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define N 64
typedef int data_t;
typedef struct seq_queue
{
data_t buf[N];
int front;//队头指针,指向出队元素下标
int rear;//队尾指针,指向最后一个元素的下一个位置
}Seq_queue;
Seq_queue *create_seq_queue();
int seq_queue_is_full(Seq_queue *s);
int seq_queue_is_empty(Seq_queue *s);
void seq_queue_push(Seq_queue *s,data_t data);
void seq_queue_pop(Seq_queue *s,data_t *data);
#endif
主函数测试:
/*===============================================
* 文件名称:main.c
* 创 建 者: xm
* 创建日期:2022年07月30日
* 描 述:
================================================*/
#include "seq_queue.h"
int main(int argc, char *argv[])
{
//顺序——循环队列
Seq_queue *s=create_seq_queue();
data_t data;
//测试
//注意顺序队列最大存N-1个元素
int n=64;
while(n--)
{
seq_queue_push(s,n);
}
while(seq_queue_is_empty(s)!=1)
{
seq_queue_pop(s,&data);
printf("%d ",data);
}
puts("");
return 0;
}
三、链式队列
队列的链式存储结构表示为链队列,它实际上是一个同时带有队头指针和队尾指针的单链表,只能尾进头出而已。
为区分结点和队列头尾指针,故分开设计结构体
typedef int data_t;
typedef struct node
{
data_t data;//数据域
struct node *next;//指针域
}Node;
typedef struct linkqueue
{
struct node *front;//队头指针,指向头结点
struct node *rear;//队尾指针,指向尾结点
}Linkqueue;
功能函数:
/*===============================================
* 文件名称:link_queue.c
* 创 建 者:xm
* 创建日期:2022年07月30日
* 描 述:
================================================*/
#include "link_queue.h"
//创建链表,返回头尾指针结构体
Linkqueue *create_link_queue()
{
Node *head=(Node *)malloc(sizeof(Node));
if(NULL==head)
{
printf("malloc head_node fallid\n");
return NULL;
}
head->data=-1;
head->next=NULL;
Linkqueue *Q=(Linkqueue *)malloc(sizeof(Linkqueue));
if(NULL==Q)
{
printf("malloc Linkqueue fallid\n");
return NULL;
}
Q->front=head;
Q->rear=head;
return Q;
}
//判空
int link_queue_is_empty(Linkqueue *queue)
{
if(queue->front==queue->rear) return 1;
else return 0;
}
//入队
void link_queue_push(Linkqueue *queue,data_t data)
{
Node *new=(Node *)malloc(sizeof(Node));
if(NULL==new)
{
printf("malloc head_node fallid\n");
return;
}
new->data=data;
new->next=queue->rear->next;
queue->rear->next=new;
queue->rear=new;
}
//出队
void link_queue_pop(Linkqueue *queue,data_t *data)
{
if(link_queue_is_empty(queue)==1)
{
printf("queue is empty\n");
return;
}
Node *temp=queue->front->next;//保存第一个节点地址
if(temp->next==NULL)
{
queue->rear=queue->front;
}
*data=temp->data;
queue->front->next=temp->next;
free(temp);
temp=NULL;
}
头文件:
/*===============================================
* 文件名称:link_queue.h
* 创 建 者:xm
* 创建日期:2022年07月30日
* 描 述:链式队列
================================================*/
#ifndef _LINKQUEUE_
#define _LINKQUEUE_
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define N 64
typedef int data_t;
typedef struct node
{
data_t data;//数据域
struct node *next;//指针域
}Node;
typedef struct linkqueue
{
struct node *front;//队头指针,指向头结点
struct node *rear;//队尾指针,指向尾结点
}Linkqueue;
//创建链表,返回头尾指针结构体
Linkqueue *create_link_queue();
//判空
int link_queue_is_empty(Linkqueue *queue);
//入队
void link_queue_push(Linkqueue *queue,data_t data);
//出队
void link_queue_pop(Linkqueue *queue,data_t *data);
#endif
主函数测试:
/*===============================================
* 文件名称:main.c
* 创 建 者:xm
* 创建日期:2022年07月30日
* 描 述:
================================================*/
#include "link_queue.h"
int main(int argc, char *argv[])
{
//链式队列
Linkqueue *Q=create_link_queue();
data_t data;
//测试
int n=10;
while(n--)
{
link_queue_push(Q,n);
}
while(link_queue_is_empty(Q)!=1)
{
link_queue_pop(Q,&data);
printf("%d ",data);
}
puts("");
return 0;
}
如有不足和有误的地方,欢迎交流指正!