队列的基本操作

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

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

队列的基本操作_第1张图片

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

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

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

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

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

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

顺序存储的对列

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

队列的基本操作_第2张图片

这种实现方案将队列元素存储在一片连续的空间里,并通过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 所示的状态。

队列的基本操作_第3张图片

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

队列的基本操作_第4张图片

// 循环顺序的队列实现文件
/
#include 
#include 
#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
#include
#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);
}

你可能感兴趣的:(数据结构)