队列

作者: 只写Bug程序猿 | 来源:发表于2020-04-16 17:14 被阅读0次

定义

队列是一种特殊的线性表,其插入和删除操作分别在线性表的两端进行,插入称为入队(enqueue),删除称为出兑(dequeue),允许入队的一端称为队尾(rear),允许出队的一端称为队头(front);

假溢出问题

首先初始化一个空队列,然后c1,c2,c3,c4,c5,c6入队,然后c1,c2,c3,c4相继出队,这就造成了队列已满的假象,其实0-3位置是空的.
为了解决这个问题,我们一般采用循环队列的方法,


循环队列
image.png

我们判空的条件是Q->rear == Q->front,那么循环队列会出现在队满的情况下Q->rear == Q->front,这就造成了无法判空的问题,那么为了解决这个问题,我们可以牺牲一个存储单元,当存储数据数量等于队列最大长度-1的情况下我们就认为已经满了无法在进行入队操作


image.png

所以:

  • 判断队空: Q.front = Q.rear
  • 判断队满: (Q.rear+1)%maxSize = Q.front

队列同栈一样也分为顺序存储,链式存储

顺序队列

定义

#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define MAXSIZE 20 /* 存储空间初始分配量 */
typedef int Status;
typedef int QElemType; /* QElemType类型根据实际情况而定,这里假设为int */

typedef struct {
    QElemType data[MAXSIZE];
    int front;          //头
    int rear;           //尾
}SQueue;
初始化空队列
Status initQueue(SQueue *Q){
   Q->front = 0;
   Q->rear = 0;
   return OK;
}
清空队列
Status clearQueue(SQueue *Q){
    Q->front = 0;
    Q->rear = 0;
    return OK;
}
队列判空
Status queueEmpty(SQueue Q){
    return Q.front == Q.rear ? TRUE : FALSE;
}
队列长度
int queueLength(SQueue Q){
    return (Q.rear - Q.front + MAXSIZE)%MAXSIZE;
}
队列入队
Status enQueue(SQueue *Q,QElemType e){
   //如果队满直接返回error
   if ((Q->rear + 1) % MAXSIZE == Q->front) {
       return ERROR;
   }
   Q->data[Q->rear] = e;
   //将队尾往后移
   Q->rear = (Q->rear + 1)%MAXSIZE;
   return OK;
}
队列出队
Status deQueue(SQueue *Q,QElemType *e){
    //如果为空直接返回error
    if (Q->rear == Q->front) {
        return  ERROR;
    }
    *e = Q->data[Q->front];
    //将队头往后移
    Q->front = (Q->front + 1)%MAXSIZE;
    return OK;
}
队列遍历
Status queueTravel(SQueue Q){
    int i = Q.front;
    while (i != Q.rear) {
        printf("%d  \n",Q.data[i]);
        i = (i+1)%MAXSIZE;
    }
    return OK;
}
函数调用
int main(int argc, const char * argv[]) {
    // insert code here...
    printf("Hello, World!\n");
    QElemType e;
    SQueue Q;
    initQueue(&Q);
    for (int i = 0; i < 11; i++) {
        enQueue(&Q, i+1);
    }
    queueTravel(Q);
    printf("队列长度%d\n",queueLength(Q));
    printf("队列是否为空%d\n",queueEmpty(Q));
    deQueue(&Q, &e);
    deQueue(&Q, &e);
    queueTravel(Q);
    printf("队列长度%d\n",queueLength(Q));
    return 0;
}

链式队列

定义
//这里的队列都是带有头结点的,
typedef struct QueueNode{
    QElemType data;
    struct QueueNode *next;
}QueueNode;
typedef QueueNode * QueuePtr;
typedef struct {
    QueueNode *front;
    QueueNode *rear;
}LinkQueue;
初始化空队列
Status initQueue(LinkQueue *Q){
    Q->front = malloc(sizeof(QueueNode));
    Q->rear = Q->front;
    //如果没开辟成功返回error
    if (Q->front == NULL) {
        return ERROR;
    }
    //将front和rear设置为null
    Q->front->next = NULL;
    return OK;
}
队列的销毁与清空
Status destoryQueue(LinkQueue *Q){
    QueuePtr temp;
    while (Q->front) {
        temp = Q->front->next;
        free(Q->front);
        Q->front = temp;
    }
    return OK;
}
Status clearQueue(LinkQueue *Q){
    QueuePtr p,q;
    Q->rear = Q->front;
    p = Q->front->next;
    Q->front->next = NULL;
    while (p) {
        q = p;
        p = p->next;
        free(q);
    }
    return OK;
}
队列的判空
Status queueEmpty(LinkQueue *Q){
    return Q->front == Q->rear;
}
获取队列长度
int queueLength(LinkQueue Q){
    int count = 0;
    QueuePtr p;
    p = Q.front;
    while (p != Q.rear) {
        count ++;
        p = p->next;
    }
    return count;
}
队列入队
Status enQueue(LinkQueue *Q,QElemType e){
    QueuePtr temp = malloc(sizeof(QueueNode));
    if (!temp) return ERROR;
    temp->data = e;
    temp->next = NULL;
    //将temp加入队列
    Q->rear->next = temp;
    //将rear后移
    Q->rear = temp;
    return OK;
}
队列出队
Status deQueue(LinkQueue *Q,QElemType *e){
    if (Q->front == Q->rear) return ERROR;
    QueuePtr temp = Q->front->next;
    *e = temp->data;
    //将front后移
    Q->front->next = temp->next;
    //若队头就是队尾,则删除后将rear指向头结点.
    if (temp == Q->rear) {
        Q->rear = temp;
    }
    free(temp);
    return OK;
}
队列遍历
Status queueTravel(LinkQueue Q){
   QueuePtr p;
   p = Q.front->next;
   while (p) {
       printf("%d\n",p->data);
       p = p->next;
       
   }
   return OK;
}
调用
int main(int argc, const char * argv[]) {
    // insert code here...
    LinkQueue Q;
    QElemType e;
    initQueue(&Q);
    enQueue(&Q, 1);
    enQueue(&Q, 2);
    enQueue(&Q, 3);
    enQueue(&Q, 5);
    queueTravel(Q);
    deQueue(&Q, &e);
    queueTravel(Q);
    return 0;
}

相关文章

  • 队列

    队列特性 对比队列和栈 基于数组的队列 对比队列学习循环队列 循环队列难点 阻塞队列 并发队列 应用:线程池中拒绝...

  • 队列

    文章结构 什么是队列 实现队列顺序队列链式队列循环队列 Java中的队列 1. 什么是队列 队列也是一种操作受限的...

  • iOS底层-- GCD源码分析(1)-- dispatch_qu

    手动目录认识队列队列的结构队列的产生主队列全局队列创建的队列管理队列 代码版本dispatch version :...

  • 队列,异步,同步,线程通俗理解

    一、队列 串行队列 并行队列 主队列(只在主线程执行的串行队列) 全局队列(系统的并行队列) 二、 任务(是否具有...

  • GCD基础总结一

    上代码~ 同步串行队列 同步并行队列 异步串行队列 异步并行队列 主队列同步 会卡住 主队列异步

  • OC多线程

    队列创建 线程与队列 队列线程间通信 队列组

  • GCD

    获得主队列 获得全局队列 串行队列 异步队列 同步队列 阻隔队列 (像栅栏一样 ) 例如 A -->栅栏 --...

  • 数据结构第三篇 队列

    队列的特性 前进先出。 我们来大致描述下进出队列的情况。 进队列 1 进队列现在队列是 12 进队列现在队列是 1...

  • 利用链表实现队列

    队列成员变量: 队列长度 队列头节点 队列尾节点队列方法: 队列包含元素个数 队列是否为空 进队操作 出队操作 d...

  • Git 常用操作命令(持续更新)

    当前更新到stash队列 查看stash队列 清空队列 删除某个队列

网友评论

    本文标题:队列

    本文链接:https://www.haomeiwen.com/subject/bpqdvhtx.html