03栈和队列--队列

3.2.1队列的基本概念

1,队列的定义

队列:是一种操作受限的线性表,只允许在表的一端进行插入,而在表的另一端进行删除。

向队列中插入元素成为入队或进队;删除元素称为出队或离队。

特性:先进先出      又称先进先出的线性表

2,队列常见的基本操作

InitQueue(&Q):初始化队列,构造空队列Q

QueueEmpty(Q):判断队列是否空,若队列Q为空返回true,否则返回false

EnQueue(&Q,&x):入队,若队列Q未满,将x加入,使之成为新的队尾。

3.2.2队列的顺序存储结构

1,队列的顺序存储

队列的顺序实现是指分配一块连续的存储单元存放队列中的元素,并附设两个指针front 和 rear 分别指示队头和队尾的位置。

设队头指针指向队头元素,队尾指针指向队尾元素的下一个位置

队列的顺序存储类型可描述为

#define Maxsize 50

typedef struct {

    ElemType  data[Maxsize];

    int  front,rear;

}Squeue

2,循环队列

为了区分队空还是队满,有三种处理方式:

1)牺牲一个单元来区分队空和队满,入队时少用一个队列单元,这是较为普遍的做法。

2)类型中增设表示元素个数的数据成员。这样,则队空的条件为Q.size==0;队满的条件为Q.size == Maxsize。这两种情况都有Q.front == Q.rear

3)类型中增设tag成员,以区分是队满还是队空。tag==0情况下,若因删除导致Q.front == Q.rear 则为队空;tag==1情况下,若因插入导致Q.front == Q.rear则为队满。

3,循环队列的操作

1)初始化

voild InitQueue(&Q){

     Q.rear = Q.front=0;     //初始化队首,队尾指针

}

2)判队空

bool isEmpty(Q){

     if(Q.rear == Q.front ){

          return true;

    }else{

          return false;

   }

}

3)入队

bool EnQueue(SqQueue  &Q,ElemType x){

    if((Q.rear+1)%MaxSize == Q.front){

          return false;   //队满

     }

     Q.data[Q.rear] = x;

     Q.rear = (Q.rear+1)%Maxsize;   // 队尾指针增加1  取模

     return true;

}

4)出队

bool DeQueue(SqQueue  &Q,ElemType &x){

      if((Q.rear+1)%MaxSize == Q.front){

               return false;   //队满

     }

      x=Q.data[Q.front];

      Q.front =(Q.front + 1)%MaxSize;   //队头指针加1   取模

      return  true;

}

3.2.3队列的链式存储结构

1,队列的链式存储

队列的链式表示称为链队列,它实际上是一个同时带有头指针和队尾指针的单链表。头指针指向队头结点,尾指针指向队尾结点,即单链表的最后一个结点。

当Q.front == null 并且  Q.rear ==null 时,链式队列为空。

出队时,首先判断队是否为空,若不为空,则取出队头元素,将其从链表中摘除,并让Q.front指向下一个结点(若该结点为最后一个结点,则置Q.front 和  Q.rear 都为 null)。

入队时,建立一个新结点,将新结点插入到链表的尾部,并且让Q.rear指向这个新插入的结点(若原队列为空队,则令Q.front也指向该结点)。

通常将链式队列设计成一个带头结点的单链表,这样插入和删除操作就统一了。

2,链式队列基本操作

3.2.4双端队列

双端队列是指允许两端都可以进行入队出队操作的队列。元素的逻辑结构是线性结构。

将队列两端分别称前端和后端,两端都可以入队和出队。

在双端队列进队时:前端进的元素排列在队列中后端进的元素前面,后端进的元素排列在队列中前端进的元素的后面。

在双端队列出队时:无论前端还是后端出队,先出的元素排列在后出的元素的前面。

猜你喜欢

转载自blog.csdn.net/will5451/article/details/81983523