队列的基本操作

本文详细介绍了队列这一数据结构,包括其特性、操作及两种常见实现方式——顺序存储和链接存储。顺序存储队列通过数组实现,利用front和rear指针管理队头和队尾;链接存储队列使用链表,通过rear指针指向尾节点进行操作。此外,还提供了具体的操作函数示例,如入队、出队、判断队列状态等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

队列是一个插入操作和删除操作受到限制的线性表数据结构

队列的插入和删除被限制在表的两端,即插入操作只能在表的一端进行,而删除操作只能在表的另端进行,因此队列又称先进先出表

  (1)允许删除的一端称为队头(Front)。

  (2)允许插入的一端称为队尾(Rear)。

  (3)当队列中没有元素时称为空队列。

  (4)队列亦称作先进先出(First In First Out)的线性表,简称为FIFO表。

     队列的修改是依先进先出的原则进行的。新来的成员总是加入队尾(即不允许"加塞"),每次离开的成员总是队列头上的(不允许中途离队),即当前"最老的"成员离队。

 【例】在队列中依次加入元素a1,a2,…,an之后,a1是队头元素,an是队尾元素。退出队列的次序只能是a1,a2,…,an。

顺序存储的对列

队列既可以采用顺序存储和链接存储来实现,下面给出了一种基于顺序存储的队列实现方案

这种实现方案将队列元素存储在一片连续的空间里,并通过data、front、rear、max四个属性元素组织成为一个结构:

-data:给出队列存储空间的起始地址;

-front:为队头指针,它指向队头元素;

-rear:为队尾指针,它指向下一个入队元素的存储位置;

-max:指明队列存储空间中最多可存储的数据元素个数(通常为了区分队列空和满,会在队列尾留一个空数据单元,此时队列最多可放max-1个数据元素

队列判断

队列为空 : 当front=rear,队列为空
队列为满 : 当front=0,rear=max-1或者 front=rear+1时
出队操作 : 出队操作的前提是队列不为空。每出队一个元素(将front处的元素出队),就将front+1
          加1后,如果front超出后最后一个位置max-1,就将front重新设置为0。
入队操作 : 入队操作的前提是队列不为满。每入队一个元素(新元素存储在rear处),就将rear+1
           加1后,如果rear超出最后一个位置max-1,就将rear重新设置为0.

同时为了讨论简单,我们假设队列元素的数据类型为整数

        

据此,只要给定指向该结构的一指针sq,就可对队列进行出队入队操作。

在给定图1的状态下,连续 2 次出队操作,这时的状态则变为如图 2 所示的状态。

在给定图 2 的状态下,连续 2 次入队操作(依次入队 23 、78 ),这时的状态则如图 3 所示。

// 循环顺序的队列实现文件
/////////////////////////////////////////////////////////
#include <stdio.h>
#include <stdlib.h>
#include "SeqQueue.h"
SeqQueue* SQ_Create(int maxlen)
{
    //创建顺序队列,队列最多存储maxlen个队列元素。
    SeqQueue* sq=(SeqQueue*)malloc(siezof(SeqQueue));
    sq->data=(T*)malloc(sizeof(T)*(maxlen+1));
    sq->front=sq->rear=0;
    sq->max=maxlen+1;
    return sq;
}
void SQ_Free(SeqQueue* sq)
//释放队列空间 以删除对列。
{
    free(sq->data);
    free(sq);
}
void SQ_MakeEmpty(SeqQueue * sq)
//将队列置空
{
    sq->front=0;
    sq->rear=0;
}
bool SQ_IsEmpty(SeqQueue* sq)
//判断队列是否为空,为空返回true,否则false。
{
    return sq->front==sq->rear;
}
bool SQ_IsFull(SeqQueue* sq)
//判断队列是否为满。为满返回true,否则返回false。
{
    return (sq->rear+1)%(sq->max)==sq->front;
}
int SQ_Length(SeqQuue* sq)
//队列长度
{
        return (sq->rear - sq-front + sq->max)%sq->max;
}
bool SQ_In(SeqQueue* sq,T x)
//将x入队。若入队失败(队列满),则返回false,否则返回true。
//赋值-加一
{
    if(SQ_IsFull(sq)){return false;}
    else{
        T* head=sq->data;
        head[sq->rear]=x;
        sq->rear=(sq->rear+1)%sq->max;
        return true;
    }
}
bool SQ_Out(SeqQueue* sq,T& item)
//从队列sq出队一个元素,返回时item为出队的值。若出队成功(队列不为空),则返回true,
// 否则(队列空),返回false,此时item不会返回有效值。
 {
     if(SQ_IsEmpty(sq)){return false;}
     else{
         T* head=sq->data;
         item=head[sq->front];
         sq->front=(sq->front+1)%sq->max; 
     }
 }
 void SQ_Print(SeqQueue* sq)
 //依次打印出队列中的每个元素
 {
     int i =sq->front;
     if(SQ_IsEmpty(sq)){printf("queue is emtpy");return;}
     for (i=sq->front; i!=sq->rear;i=(i+1)%sq->max){
         printf("%d",sq->data[i]);
     }
     print("\n");
          
 }

2.实现一个链接存储的队列

链式队列的定义:队列的存储除了顺序存储之外也可以采用链接存储方法来实现。

#include<stdio.h>
#include<stdlib.h>
#include "CLnkQueue.h"
LNode* CLQ_Create()
//创建一个队列
{
    LNode* rear=(LNode*)malloc(sizeof(LNode));
    rear->data=0;
    rear->next=rear;
    return rear;
}
void CLQ_Free(LNode* rear)
//rear指向尾结点
{
    CLQ_MakeEmpty(rear);
    free(rear);
}
void CLQ_MakeEmpty(LNode* & rear)
//rear指向尾结点。
//将队列变为空队列
{
    T item;
    while(!CLQ_IsEmpty(rear))
        CLQ_Qut(rear,item);
}
bool CLQ_IsEmpty(LNode* rear)
//判断队列是否为空表
{return rear->next=rear;}
int CLQ_Length(LNode* rear)
//返回队列长度,rear指向尾结点
{
    return rear->next-data;
}
void CLQ_IN(LNode* &rear,T x)
//入队列,新结点加入链表尾部。rear指向尾结点
{
    LNode* newNode=new LNode;
    newNode->data=x;
    newNode->next=rear->next;
    rear->next=newNode;
    rear=newNode;
    rear->next->data++;
    }
bool CLQ_Qut(LNode* & rear,T& item)
//出队列。空队列时,返回值为false。rear指向尾结点。
{
    if(CLQ_IsEmpty(rear)){return false;}
    else if (rear->next->data==1)
    {
        rear=rear->next;
        rear->next=rear;
        rear->data--;
    }
    else{
        LNode* addNode=rear->next;
        addNode->next=addNode->next->next;
        addNode->data--;
        return true;
    }
}
bool CLQ_Head(LNode* rear, T& item)
// rear 指向尾结点
//获取队列头。空队列时返回值为false。
{
    if(CLQ_IsEmpty(rear))
    {
        return false;
    }
    item=rear->next->next->data;
    return true;
}
void CLQ_Print(LNode* rear)
//打印队列
{
    if(CLQ_IsEmpty(rear))
    {
        printf("The queue is : empty.\n");
        return;
    }
    LNode* node=rear->next->next;
    do
    {
        printf("%d",node->data);
        node=node->next;
    }while(node!=rear->next);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值