文章目录
数据结构—P5 队列
简介
队列
队列(queue)是只允许在一端进行插入操作,而在另一端进行删除操作的线性表
队列是一种先进先出(First In First Out)的线性表,简称FIFO
循环队列
但是普通的队列会出现假溢出的现象,处理的办法就是后面满了,就再从头开始,也就是头尾相接的循环,这里把队列的这种头尾相接的顺序存储结构称为循环队列
链式队列
队列的链式存储结构,其实就是线性表的单链表,只不过它只能尾进头出而已,这里把这种线性单链表叫做链式队列
循环队列的实现
创建结构体
编写Makefile
test:test.o sequeue.o
gcc -o test test.o sequeue.o
test.o:test.c sequeue.h
gcc -c test.c
sequeue.o:sequeue.c sequeue.h
gcc -c sequeue.c
.PHONY:clean
clean:
rm *.o
编写sequeue.h
#ifndef __SEQUEUE_H__
#define __SEQUEUE_H__
//定义int类型的数据的别名为data_t
typedef int data_t;
//定义循环队列结构体,并创建结构体的别名sequeue
#define N 128
typedef struct{
data_t data[N];
int up;
int down;
}sequeue;
创建与销毁
创建队列
编写sequeue.h
编写sequeue.c
sequeue * sequeue_create(){
sequeue *sq;
if((sq = (sequeue *)malloc(sizeof(sequeue))) == NULL){
printf("malloc is failed\n");
return NULL;
}
memset(sq->data,0,sizeof(sq->data));
sq->up = sq->down = 0;
return sq;
}//创建表
销毁队列
编写sequeue.h
编写sequeue.c
sequeue * sequeue_free(sequeue *sq){
if(sq == NULL){
printf("sq is NULL\n");
return NULL;
}
free(sq);
sq = NULL;
return NULL;
}//释放表
int sequeue_clear(sequeue *sq){
if(sq == NULL){
printf("sq is NULL\n");
return -1;
}
sq->up =sq->down = 0;
return 0;
}//清空表
状态属性
编写sequeue.h
编写sequeue.c
int sequeue_isempty(sequeue *sq){
if(sq == NULL){
printf("sq is NULL\n");
return -1;
}
if(sq->up == sq->down){
return 1;
}else{
return 0;
}
}//表是否为空
int sequeue_isfull(sequeue *sq){
if(sq == NULL){
printf("sq is NULL\n");
return -1;
}
if((sq->down + 1) % N == sq->up){
return 1;
}else{
return 0;
}
}//表是否为满
尾部插入
编写sequeue.h
编写sequeue.c
int sequeue_downqueue(sequeue *sq,data_t value){
if(sq == NULL){
printf("sq is NULL\n");
return -1;
}
if((sq->down + 1) % N == sq->up){
printf("sequeue is full\n");
return -1;
}
sq->data[sq->down] = value;
sq->down = (sq->down + 1) % N;
return 0;
}//尾部插入
头部删除
编写sequeue.h
编写sequeue.c
data_t sequeue_upqueue(sequeue *sq){
data_t value;
value = sq->data[sq->up];
sq->up = (sq->up + 1) % N;
return value;
}//头部删除
查询操作
编写sequeue.h
编写sequeue.c
int sequeue_show(sequeue *sq){
int i;
if(sq == NULL){
printf("sq is NULL\n");
return -1;
}
if(sequeue_isempty(sq)){
printf("sqstack is empty\n");
}
printf("sequeue:\n");
printf(" pos ");
for(i = sq->up;i <= sq->down-1;i++){
printf("%d ",i);
}
printf("\n");
printf("value ");
for(i = sq->up;i <= sq->down-1;i++){
printf("%d ",sq->data[i]);
}
printf("\n");
}//查询并显示所有内容
编写test.c
#include <stdio.h>
#include "sequeue.h"
int main(int argc, const char *argv[])
{
sequeue *sq;
int value;
if((sq = sequeue_create()) == NULL){
return -1;
}
while(1){
printf("input(-1quit):");
scanf("%d",&value);
if(value == -1)break;
sequeue_downqueue(sq,value);
sequeue_show(sq);
}
while(!sequeue_isempty(sq)){
sequeue_upqueue(sq);
sequeue_show(sq);
}
sequeue_free(sq);
return 0;
}
测试程序
链式队列的实现
创建结构体
编写Makefile
test:test.o lkqueue.o
gcc -o test test.o lkqueue.o
test.o:test.c lkqueue.h
gcc -c test.c
lkqueue.o:lkqueue.c lkqueue.h
gcc -c lkqueue.c
.PHONY:clean
clean:
rm *.o
编写lkqueue.h
#ifndef __LKQUEUE_H__
#define __LKQUEUE_H__
#include <stdio.h>
//定义int类型的数据的别名为data_t
typedef int data_t;
//定义链式队列结构体,并创建结构体别名为listnode和*lklist
typedef struct node{
data_t data;
struct node *next;
}listnode,*lklist;
//定义链式队列头结构体和尾结构体
typedef struct{
lklist up;
lklist down;
}lkqueue;
创建与销毁
创建队列
编写lkqueue.h
编写lkqueue.c
lkqueue *lkqueue_create(){
lkqueue *lq;
if((lq = (lkqueue *)malloc(sizeof(lkqueue))) == NULL){
printf("malloc is failed\n");
return NULL;
}
lq->up = lq->down = (lklist)malloc(sizeof(listnode));
if(lq->up == NULL){
printf("malloc is failed\n");
return NULL;
}
lq->up->data = 0;
lq->down->data = 0;
return lq;
}//创建表
销毁队列
编写lkqueue.h
编写lkqueue.c
lkqueue *lkqueue_free(lkqueue *lq){
lklist p;
if(lq == NULL){
printf("lq is NULL");
return NULL;
}
while(lq->up){
p = lq->up;
lq->up = p->next;
free(p);
}
free(lq);
lq == NULL;
return NULL;
}//释放表
int lkqueue_clear(lkqueue *lq){
lklist p;
if(lq == NULL){
printf("lq is NULL");
return 0;
}
while(lq->up->next){
p = lq->up;
lq->up = p->next;
free(p);
p = NULL;
}
return 0;
}//清空表
状态属性
编写lkqueue.h
编写lkqueue.c
int lkqueue_isempty(lkqueue *lq){
if(lq == NULL){
printf("lq is NULL\n");
return -1;
}
if(lq->up == lq->down){
return 1;
}else{
return 0;
}
}//表是否为空
尾部插入
编写lkqueue.h
编写lkqueue.c
int lkqueue_downqueue(lkqueue *lq,data_t value){
lklist p;
if(lq == NULL){
printf("lq is NULL\n");
return -1;
}
if((p = (lklist)malloc(sizeof(listnode))) == NULL){
printf("malloc is failed\n");
return -1;
}
p->data = value;
p->next = NULL;
lq->down->next = p;
lq->down = p;
return 0;
}//表尾部插入
头部删除
编写lkqueue.h
编写lkqueue.c
data_t lkqueue_upqueue(lkqueue *lq){
lklist p;
if(lq == NULL){
printf("lq is NULL\n");
return -1;
}
p = lq->up;
lq->up = p->next;
free(p);
p = NULL;
return (lq->up->data);
}//表头部删除
查询操作
编写lkqueue.h
编写lkqueue.c
int lkqueue_show(lkqueue *lq){
lklist p;
if(lq == NULL){
printf("lq is NULL\n");
return -1;
}
p = lq;
printf("lkqueue:\n");
while(p->next != NULL){
printf("%d ",p->next->data);
p = p->next;
}
printf("\n");
}//查询并显示所有内容
编写test.c
#include <stdio.h>
#include "lkqueue.h"
int main(int argc, const char *argv[])
{
lkqueue *lq;
int value;
if((lq = lkqueue_create()) == NULL){
return -1;
}
while(1){
printf("input(-1quit):");
scanf("%d ",&value);
if(value == -1){
break;
}
lkqueue_downqueue(lq,value);
lkqueue_show(lq);
}
while(!lkqueue_isempty(lq)){
lkqueue_upqueue(lq);
lkqueue_show(lq);
}
lkqueue_free(lq);
return 0;
}