数据结构——队列

一.队列介绍

1.什么是队列

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

允许进行存入操作的一端称为"队尾"

允许进行删除操作的一端称为"队头"

当线性表中没有元素时,称为"空队"

特点 :先进先出(FIFO)

队列有一下两种

2.顺序队列

复制代码
typedef  int  data_t ;    /*定义队列中数据元素的数据类型*/
#define  N  64	    /*定义队列的容量*/

typedef  struct {
      data_t  data[N] ;   /*用数组作为队列的储存空间*/
      int  front, rear ;     /*指示队头位置和队尾下一个位置的指针*/
} sequeue_t ; 	     /*顺序队列类型定义*/

顺序队列我们常用循环队列,循环队列有个特点就是为了区别空队和满队,满队元素个数比数组元素个数少一个

代码框架

sequeue.h

复制代码
typedef int datatype ;
#define N 128

typedef struct 
{
        data_t data[N];
        int front,rear;

}sequeue;

sequeue *queue_create();
int enqueue(sequeue *sq,datatype x);
datatype dequeue(sequeue *sq);//出队
int queue_empty(sequeue *sq);
int queue_full(sequeue *sq);
int queue_clear(sequeue *q);
sequeue * queue_free(sequeue *sq);

sequeue.c

复制代码
#include <stdio.h>
#include <stdlib.h>
#include "sequeue.h"
#include <string.h>

sequeue *queue_create(){
        sequeue *sq;
        if((sq=(sequeue *)malloc(sizeof(sequeue)))==NULL){
                printf("malloc failed\n");              
                return NULL;
        }
        memset(sq->data,0,sizeof(data));
        sq->front=sq->rear=0;

        return sq;
}
int enqueue(sequeue *sq,datatype x){
        if(sq==NULL){
                printt("sq is NULL\n");
                return -1;
        }       

}

test.c

复制代码
#include<stdio.h>
#include "sequeue.h"

int main()
{
        sequeue *sq;
        sq=queue_create();
        if(sq==NULL){
                return -1;
        }
        enqueue(sq,10);
        enqueue(sq,100);
        enqueue(sq,1000);

        while(!queue_empty(sq)){
                printf("dequeue:%d\n",dequeue(sq));

        }


        return 0;
}

具体代码编写

创建队列

创建一个结构体指针,分配内存,判断是否分配成功,成功之后给成员data初始化,让队尾和队头都为0;

sequeue *queue_create(){

sequeue *sq;

if((sq=(sequeue *)malloc(sizeof(sequeue)))==NULL){

printf("malloc failed\n");

return NULL;

}

memset(sq->data,0,sizeof(data));

sq->front=sq->rear=0;

return sq;

}

入队

判断rear向后移动一位,rear与front是否相等,相等说明队满了,不等进行入队操作

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;

}

出队

datatype dequeue(sequeue *sq){//出队

datatype ret;

if(sq==NULL){

printf("sq is NULL\n");

return -1;

}

ret=sq->data[sq->front];

sq->front=(sq->front+1)%N;

return ret;

}

判断队列情况

int queue_empty(sequeue *sq){

if(sq==NULL){

printf("sq is NULL\n");

return -1;

}

return (sq->front==sq->rear?1:0);

}

int queue_full(sequeue *sq){

if(sq==NULL){

printf("sq is NULL\n");

return -1;

}

if((sq->rear+1%N)==sq->front){

printf("sequeue is full\n");

return -1;

}

else

return 0;

}

清空队列元素

int queue_clear(sequeue *sq){

if(sq==NULL){

printf("sq is NULL\n");

return -1;

}

sq->front=sq->rear=0;

return 0;

}

释放队列内存

sequeue * queue_free(sequeue *sq){

if(sq==NULL){

printf("sq is NULL\n");

return NULL;

}

free(sq);

sq=NULL;

return NULL;

}

3.链式队列

linkqueue.h

复制代码
typedef struct node
{
        data_t data;
        struct node *next;
}listnode,*linklist;

typedef struct{
        linklist front;
        linklist rear;
}linkqueue;

linkqueue *queue_crearte();
int enqueue(linkqueue *lq,datatype x);
datatype dequeue(lingkqueue *lq);
int queue_empty(linkqueue *le);
int queue_clear(linkqueue *lq);
int queue_free(linkqueue *lq);

linkqueue.c

复制代码
#include "linkqueue.h"

int main()
{
        linkqueue *lq;
        lq=queue_create();
        if(lq==NULL){
                return -1;
                }
        enqueue(lq,10);
        enqueue(lq,100);
        enqueue(lq,1000);
        enqueue(lq,200);

        while(!queue_empty(lq)){

                printf("dequeue:%d\n",dequeue(lq));
        }
        queue_free(lq);


        return 0;
}

创建队列

单链表是有头指针的,如果为空front与rear也是要指向一个头节点,并且两个都需要申请内存,其次front和rear都是一个结构体,结构体里面的data,next需要初始化

复制代码
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 is failed\n");
                return NULL;
        }

        lq->front->data=0;
        lq->front->next=NULL;//或则lq->rear->next=NULL,只需对一个就行,因为指向同一个内存空间

        return lq;
}

入队

需要封装一个节点p去指向入队的元素,封装节点需要创建,申请内存,之后去指向入队元素。

之后rear->next指向p,再移动rear到p

复制代码
int enqueue(linkqueue *lq,data_t x){
        linklist p;
        if(lq==NULL){
                printf("lq is NULL");
                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;
}

出队

出队就是把front往后移动,frear->data初值是没有数据的,往后移动一位就是队的第一个数据,此时返回front->data就是把第一个入队的出队了;front的移动需要一个指针p来协助,以及用p释放出队的元素的内存

复制代码
data_t dequeue(linkqueue *lq){
        linklist p;

        if(lq==NULL){
                printf("lq is NULL");
                return -1;
        }

                p=lq->front;
                lq->front=p->next;
                free(p);
                p=NULL;

        return (lq->front->data);
}

是否为空

查看front与rear是否相同就行,相同就是空

int queue_empty(linkqueue *lq){

if(lq==NULL){

printf("lq is NULL");

return -1;

}

return (lq->front==lq->rear ? 1:0);

}

清空队列

清空队列需要留一个,节点,所以while的判断调节是ql->front->next是否为空

nt queue_clear(linkqueue *lq){

linklist p;

if(lq==NULL){

printf("lq is NULL");

return -1;

}

while(lq->front->next){

p=lq->front;

lq->front=p->next;

printf("free:%d\n",p->data);

free(p);

p=NULL;

}

return 0;

}

释放内存

先while循环释放内层,再释放外层

复制代码
linkqueue * queue_free(linkqueue *lq){
         linklist p;

        if(lq==NULL){
                printf("lq is NULL");
                return NULL;
        }

        while(lq->front){
                p=lq->front;
                lq->front=p->next;
                printf("free:%d\n",p->data);
                free(p);
                p=NULL;
        }
        free(lq);
        lq=NULL;

        return NULL;
}
                                                                               96,9          98%
相关推荐
双叶8367 分钟前
(C++)学生管理系统(正式版)(map数组的应用)(string应用)(引用)(文件储存的应用)(C++教学)(C++项目)
c语言·开发语言·数据结构·c++
学不动CV了3 小时前
数据结构---链表结构体、指针深入理解(三)
c语言·arm开发·数据结构·stm32·单片机·链表
算法_小学生5 小时前
LeetCode 287. 寻找重复数(不修改数组 + O(1) 空间)
数据结构·算法·leetcode
Wo3Shi4七8 小时前
哈希冲突
数据结构·算法·go
V我五十买鸡腿9 小时前
顺序栈和链式栈
c语言·数据结构·笔记·算法
七灵微10 小时前
数据结构实验习题
数据结构
杰克尼20 小时前
BM5 合并k个已排序的链表
数据结构·算法·链表
xiaolang_8616_wjl21 小时前
c++文字游戏_闯关打怪
开发语言·数据结构·c++·算法·c++20
hqxstudying1 天前
Java创建型模式---单例模式
java·数据结构·设计模式·代码规范
sun0077001 天前
数据结构——栈的讲解(超详细)
数据结构