对队列的操作和算法
来源:互联网 发布:如何学好口语知乎 编辑:程序博客网 时间:2024/04/27 13:56
一、队列的定义
队列(queue)是一种先进先出的线性表。它只允许在表的一端进行插入,而在另一端删除元素。
允许插入的一端叫做队尾(rear),允许删除的一端则称为对头(front)。
队列一般也分为两种:
链式队列:用链表实现;
静态队列:用数组实现(静态队列通常都必须是循环队列)。
一般用循环队列比较多,这里也只是讲述循环队列。
二、循环队列需要弄清楚的几个问题
1、静态队列为什么必须是循环队列
答:因为无论是入队还是出队,rear和front都只能加不能减,如果用传统意义的数组实现队列,比front元素下标小的数组空间就浪费了。
2、.循环队列需要几个参数来确定
答:循环队列需要2个参数,front和rear
3、循环队列各个参数的含义
(1)队列初始化时,front和rear值都为零;
(2)当队列不为空时,front指向队列的第一个元素,rear指向队列最后一个元素的下一个位置;
(3)当队列为空时,front与rear的值相等,但不一定为零;
4、循环队列入队的伪算法
(1)把值存在rear所在的位置;
(2)rear=(rear+1)%maxsize ,其中maxsize代表数组的长度;
4、循环队列出队的伪算法
(1)先保存出队的值;
(2)front=(front+1)%maxsize ,其中maxsize代表数组的长度;
5、如何判断循环队列是否为空
if(front==rear)
队列空;
else
队列不空;
6、如何判断循环队列是否为满
这个问题比较复杂,假设数组的存数空间为7,此时已经存放六个元素了,如果在往数组中添加一个元素,则rear=front;此时,队列满与队列空的判断条件front=rear相同,这样的话我们就不能判断队列到底是空还是满了;
解决这个问题有两个办法:
一是增加一个参数,用来记录数组中当前元素的个数;
二是少用一个存储空间,也就是数组的最后一个存数空间不用,当(rear+1)%maxsiz=front时,队列满。
一般用第二种方法。
三、用C语言实现
关于循环队列的结构,可以参考严蔚敏的《数据结构》,那里讲得比较清楚。
/*2016年9月18日20:31:06循环队列*/#include<stdio.h>#include<malloc.h>#include<stdlib.h>#define MAXQSIZE 6 //最大队列长度typedef struct Queue{int * pBase; //用来储存数组的首地址int front; //队头,因为是用数组实现,所以可以不用指针int rear; //队尾} QUEUE, * PQUEUE;//函数声明void init_queue(PQUEUE pQ);bool en_queue(PQUEUE pQ, int val);bool out_queue(PQUEUE pQ, int *val);void traverse_queue(PQUEUE pQ);bool is_full(PQUEUE pQ);bool is_empty(PQUEUE pQ);int main(void) //主函数主要用来测试各个函数的正确性,并无实际用途{QUEUE Q;int val;init_queue(&Q); //初始化队列en_queue(&Q, 1);en_queue(&Q, 2);en_queue(&Q, 3);en_queue(&Q, 4);en_queue(&Q, 5);out_queue(&Q, &val);en_queue(&Q, 6);en_queue(&Q, 7);traverse_queue(&Q);return 0;}void init_queue(PQUEUE pQ) //初始化队列{//构造一个空队列pQ->pBase = (int *)malloc(sizeof(int) * MAXQSIZE); //动态分配一块内存给数组if(NULL == pQ->pBase){printf("内存分配失败,程序终止!\n");exit(-1);}pQ->front = pQ->rear = 0; return;}bool is_full(PQUEUE pQ) //判断队列是否满{if((pQ->rear+1) % MAXQSIZE == pQ->front)return true;else return false;}bool is_empty(PQUEUE pQ) //判断队列是否满{if(pQ->rear == pQ->front)return true;else return false;}void traverse_queue(PQUEUE pQ) //遍历输出{int i = pQ->front;while(pQ->rear != i){printf(" %d ", pQ->pBase[i]);i = (i+1) % MAXQSIZE;}printf("\n");return;}bool en_queue(PQUEUE pQ, int val) //入队{if(is_full(pQ)){return false;}else{pQ->pBase[pQ->rear] = val;pQ->rear = (pQ->rear+1) % MAXQSIZE;return true;}}bool out_queue(PQUEUE pQ, int *pVal) //出队{if(is_empty(pQ)){return false;}else{*pVal = pQ->pBase[pQ->front];pQ->front = (pQ->front + 1) % MAXQSIZE;return true;}}
- 对队列的操作和算法
- 栈和队列算法三之队列的基本操作
- 对栈的操作和算法实现
- 栈和队列算法一之栈的基本操作
- 顺序队列的算法操作
- 链队列的算法操作
- 栈和队列的操作
- 栈和队列的操作
- 妙趣横生的算法之队列的操作
- 用两个栈实现队列的入队和出对操作
- 数据结构 ——队列操作的算法
- 【算法设计-优先队列】优先队列的实现与操作
- 算法提高 队列操作
- 算法提高 队列操作
- 算法提高 队列操作
- 算法提高 队列操作
- 算法提高 队列操作
- 算法提高 队列操作
- RCNN学习笔记(5):faster rcnn
- Maven详解之聚合与继承
- NoHttp,volley,okhttp这三个有什么区别,哪个好用
- linux下查找某文件,文件夹的命令和方法
- 解决checkbox的attr(checked)一直为undefined问题
- 对队列的操作和算法
- OCR图文识别软件是怎样禁用自动处理的
- ERP数据库显示到前段表达方法
- [C#基语法]之C#命名空间(namespace)
- DoorSignView
- LeetCode: Reorder List
- Android sqlite联合主键的使用
- 《Hadoop基础教程》之初识Hadoop
- Connection reset by peer: socket write error错误分析