队列

作者: SkyHive | 来源:发表于2017-10-14 16:55 被阅读0次

队列

队列是一种可以实现先进先出(first in first out,FIFO)的存储结构。与栈不一样的是,队列规定只在一端进行插入操作,在另一端进行删除操作。允许插入的一端叫做队尾(rear),允许删除的一端叫做队首(front)。

分类

  • 链式队列:用链表实现。
  • 静态队列:用数组实现。(为了解决假溢出现象,静态队列通常都必须是循环队列)

循环队列

参数:front、rear
  • rear所指的单元始终为空
  • 队列初始化:front和rear的值都是0。
  • 队列非空:front指向队列的第一个元素;rear指向队列的最后一个有效元素的下一个元素。
  • 队列空:front和rear值相等,但不一定是0。
算法解析

1.入队:将值存入rear所代表的位置r

  • 错误写法:r=r+1
  • 正确写法:r=(r+1)%数组长度

2.出队:
f=(f+1)%数组长度

3.判断循环队列是否为空

rear = front

4.判断循环队列是否已满

  • 多增加一个参数标志满或者空(一般不用此方式)
  • 少用一个元素:如果(r+1)%数组长度==f表示循环队列已满
代码实现

1.队列数据建构

typedef struct queue {
    int *p;
    int front;
    int rear;
    int maxsize;
}Queue;

2.初始化队列

void CreateQueue(Queue *Q,int maxsize){
    Q->p = (int*)malloc(sizeof(int)*maxsize);
    if(!Q->p){
        printf("Memory allocation failure!");
        exit(-1);
    }
    Q->front = Q->rear;
    Q->maxize = maxsize;
}

3.判断循环队列是否为满

int isFull(Queue *Q){
    if ((Q->rear+1)%Q->maxsize == Q->front)
        return 1;
    else
        return 0;
}

4.判断循环队列是否为空

int isEmpty(Queue *Q){
    if(Q->rear == Q->front)
        return 1;
    else
        return 0;
}

5.入队操作

void Enter(Queue *Q,int val){
    if (isFull(Q)){
        printf("The queue is full!");
        return;
    }
    else{
        Q->p[Q->rear] = val;
        Q->rear = (Q->rear+1)%Q->maxsize;
    }
}

6.出队操作

void Delete(Queue *Q,int *val){
    if(isEmpty(Q))
        return 0;
    else{
        *val = Q->p[Q->front];
        Q->front=(Q->front+1)%Q->maxszie;
        printf("Get out of the queue successfully!");
    }
}

7.遍历操作

void Traverse(Queue *Q){
    int i = Q->front;
    printf("The items in queue are:\n");
    while(i%Q->maxsize!=Q->rear){
        printf("%d",Q->p[i]);
        i=(i+1)%Q->maxsize;
    }
    printf("\n");
}

链式队列

链式队列实现和链式栈相差不多,只是将删除操作放在了另外一端,有效的解决了顺序队列存储空间不足的缺陷。

代码实现

1.队列节点构建

typedef struct Node{
    int data;       //数据域
    struct Node *next;      //指针域
}Node;
typedef struct{
    Node *front;
    Node *rear;
}Queue;

2.队列初始化

int InitQueue(Queue *Q){
    Node *head = (Node*)malloc(sizeof(Node));
    if(!head){
        printf("Memory allocation failed!\n");
        return ;
    }
    head->next = NULL;
    Q->rear = Q->front = head;      //front和rear都指向头指针
    printf("Init successfully!\n");
    return 0;
}

3.入队操作

int Enter(Queue *Q,int item){
    Node *s = (Node*)malloc(sizeof(Node));
    if(!s){
        printf("Memory allocation failed!\n");
        return ;
    }
    s->next = NULL;
    s->data = item;
    Q->rear->next = s;
    Q->rear = s;
    return 0;
}

4.出队操作

void Delete(Queue *Q,int *item){
    if(Q->front == Q->rear){
        printf("The queue is empty!\n");
        return;
    }
    Node *p;
    p = Q->front->next;     //先将要出栈的节点存在P中
    Q->front->next = p->next;       //重新构造队头元素的后继
    *item = p->data;            //保存出队的数据;
    if(Q->rear == p)        //判断删除的节点是否为队尾元素
        Q->rear = Q->front;
    free(p);
}

5.遍历元素

void Traverse(Queue *Q){
    if(Q->front == Q->rear){
        printf("The queue is empty!\n");
    }
    Node *p = Q->front->next;
    while(p){
        printf("%d",p->data);
        p = p->next;
    }
    printf("\n");
}

相关文章

  • 队列

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

  • 队列

    文章结构 什么是队列 实现队列顺序队列链式队列循环队列 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/vfqfuxtx.html