队列:
定义:
一种可以实现“先进先出”的存储结构
分类:
链式队列(用链表实现的)
静态队列(用数组实现的)
静态队列通常必须是循环队列
循环队列的讲解:
1.静态队列为什么必须是循环队列
2.循环队列需要几个参数来确定
两个参数:
front
rear
3.循环队列各个参数的含义
2个参数不同场合有不同含义
建议初学者先记住,再慢慢体会
1>.队列初始化front和rear的值都为零 2>.队列非空front代表的是队列的第一个元素rear代表的是队列的最后一个有效元素的下一个元素
3>.队列空front和rear的值相等,但不一定是零
4.循环队列入队伪算法讲解
两步完成:
1.将值存入rear所代表的位置
2.错误的写法rear = rear+1;
正确的写法:rear = (rear+1)%数组的长度
5.循环队列出队伪算法讲解
front = (front+1)%数组长度
6.如何判断循环队列是否为空
如果front与rear的值相等,则该队列一定为空
7.如何判断循环队列是否为满
预备知识:
front的值可能比rear大
也可能比rear小
也可能相等
两种方式:
1.多增加一个表标识参数(数组有效长度)
2.少用一个元素【通常使用第二种】
如果rear和front的值紧挨着,则队列已满
C语言伪算法表示:
if((rear+1)%数组长度 == f)
已满
else
不满
队列算法:
入队
出队
# include <stdio.h> # include <malloc.h> typedef struct Queue { int * pBase; int front; int rear; }QUEUE; void init(QUEUE *); bool en_queue(QUEUE *, int val); //入队 void traverse_queue(QUEUE *); bool full_queue(QUEUE *); bool out_queue(QUEUE *, int *); bool emput_queue(QUEUE *); int main(void) { QUEUE Q; int val; init(&Q); en_queue(&Q, 1); en_queue(&Q, 2); en_queue(&Q, 3); en_queue(&Q, 4); en_queue(&Q, 5); en_queue(&Q, 6); en_queue(&Q, 7); en_queue(&Q, 8); traverse_queue(&Q); if ( out_queue(&Q, &val) ) { printf("出队成功,队列出队的元素是: %d ", val); } else { printf("出队失败! "); } traverse_queue(&Q); return 0; } void init(QUEUE *pQ) { pQ->pBase = (int *)malloc(sizeof(int) * 6);//第一个元素的地址,也可以当作它是数组,数组长度为6 pQ->front = 0; pQ->rear = 0; } bool full_queue(QUEUE * pQ) { if ( (pQ->rear + 1) % 6 == pQ->front ) return true; else return false; } bool en_queue(QUEUE * pQ, int val) { if ( full_queue(pQ) ) { return false; } else { pQ->pBase[pQ->rear] = val; pQ->rear = (pQ->rear+1) % 6; return true; } } void traverse_queue(QUEUE * pQ) { int i = pQ->front; while (i != pQ->rear) { printf("%d ", pQ->pBase[i]); i = (i+1) % 6; } printf(" "); return; } bool emput_queue(QUEUE * pQ) { if ( pQ->front == pQ->rear ) return true; else return false; } bool out_queue(QUEUE * pQ, int * pVal) { if ( emput_queue(pQ) ) { return false; } else { *pVal = pQ->pBase[pQ->front]; pQ->front = (pQ->front+1) % 6; return true; } }
队列的具体应用:
所有和时间有关的额操作都有队列的影子