玩转《数据结构》队列

29 阅读3分钟

1.队列的基本概念

1)定义

  • 队列简称队,也是一种操作受限的线性表,只允许在表的一端进行插入,而在另一端进行删除。向队列中插入元素称为入队;删除元素成为出队

2)特性

  • 先进先去

3)队头

  • 允许删除的一端

4)队尾

  • 允许插入的一端

5)空队列

  • 不含任何元素的空表

6)队列常见的基本操作

  • InitQueue(&Q)

    • 初始化队列,构造一个空队列Q
  • QueueEmpty(Q)

    • 判队列空,若队列Q为空返回true,否则返回false
  • EnQueue(&Q,x)

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

    • 出队,若队列Q非空,删除队头元素,并用x返回
  • GetHead(Q,&x)

    • 读队头元素,若队列Q非空,则将队头元素赋值给x

2.队列的顺序存储结构

1)队列的顺序存储

  • 定义

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

        #define MaxSize 50
           typedef struct{
             ElemType data[MaxSize];
             int front,rear;
           }SqQueue;
  • 初始状态

    • Q.front==Q.rear==0
  • 进队操作

    • 队不满时,先送值到队尾元素,再将队尾指针加1
  • 出队操作

    • 队不空时,先取队头元素,再将队头指针加1

2)循环队列

  • 将顺序队列臆造为一个环状的空间,即把存储队列元素的表从逻辑上视为一个环,称为循环队列

  • 初始时

    • Q.front=Q.rear=0
  • 队首指针进1

    • Q.front=(Q.front+1)%MaxSize
  • 队尾指针进1

    • Q.rear=(Q.rear+1)%MaxSize
  • 出队入队时

    • 指针都按顺时针方向进1
  • 队空队满区分方式

    • 牺牲一个单元来区分

      • 队满条件

        • (Q.rear+1)%MaxSize==Q.front
      • 队空条件

        • Q.rear==Q.front
    • 增设表示元素个数的数据成员

      • 队满条件

        • Q.size==MaxSize
      • 队空条件

        • Q.size==0
    • 类型中增设tag数据成员

      • 队满条件

        • Q.front=Q.rear;tag==1(插入导致)
      • 队空条件

        • Q.front=Q.rear;tag==0(删除导致)

3)循环队列的操作

  • 初始化
         void InitQueue(SqQueue &Q){
             Q.rear==Q.front=0;
         }
  • 队列空
         bool isEmpty(SqQueue &Q){
           if(Q.rear==Q.front) return true;
           else return false;
         }
  • 入队
         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;
            return true;
         }
  • 出队
         bool DeQueue(SqQueue &Q,ElemType &x){
             if(Q.rear==Q.front) return false;
             X=Q.data[Q.front];
             Q.front=(Q.front+1)%MaxSize;
             return true;
         }

3.队列的链式存储结构

1)队列的链式存储

  • 定义

    • 队列的链式表示称为链队列,它实际上是一个同时带队头指针和队尾指针的单链表。头指针指向队头结点,尾指针指向队尾结点
  • 存储类型

    • typedef struct LinkNode{ ElemType data; struct LinkNode *next; }LinkNode; typedef struct{ typedef *front *rear; }LinkQueue;
  • 建议采用有头结点链表

2)链式队列的基本操作

  • 初始化
         void InitQueue(LinkQueue &Q){
           Q.rear=Q.front=(LinkNode*)malloc(sizeof(LinkNode)); //建立头结点
           Q.front->next=NULL; //初始为空
         }
  • 判队空
	  bool isEmpty(LinkQueue Q){
	    if(Q.rear==Q.front) return true;
	    else return false;
	  }
  • 入队
	  bool EnQueue(LinkQueue &Q,ElemType x){
	     LinkNode *s=(LinkNode*)malloc(sizeof(LinkNode)); 
	     s.data=x; s->next=NULL;
	     Q.rear->next=s;
	     Q.rear=s;
	  }
  • 出队
	  bool DeQueue(LinkQueue &Q,ElemType &x){
	     if(Q.rear=Q.front) return false;
	     LinkNode *p=Q.front->next;
	     x=p->data;
	     Q.front->next=p->next;
	     if(Q.rear==p){
	       Q.rear=Q.front;
	     free(p);
	     return true;
	  }

4.双端队列

1)定义

  • 两端都可以进行入队和出队操作的队列

2)输出受限的双端队列

  • 允许一端进行插入和删除,但在另一端只允许插入

3)输入受限的双端队列

  • 允许一端进行插入和删除,但在另一端只允许删除