一:概念
队列是一个”先进先出“的线性表,牛X的名字就是“First in First Out(FIFO)”,
生活中有很多这样的场景,比如读书的时候去食堂打饭时的”排队“。当然我们拒绝插队。
二:存储结构
前几天也说过,线性表有两种”存储结构“,① 顺序存储,②链式存储。当然“队列”也脱离
不了这两种服务,这里我就分享一下“顺序存储”。
顺序存储时,我们会维护一个叫做”head头指针“和”tail尾指针“,分别指向队列的开头和结尾。
三:常用操作
队列的操作一般分为:
①: 初始化队列。
②: 出队。
③: 入队。
④: 获取队头。
⑤: 获取队长。
1:初始化队列
这个很简单,刚才也说过了,队列是用一个head和tail的指针来维护。分别设置为0即可。
2:出队
看着“队列”的结构图,大家都知道,出队肯定跟head指针有关,需要做两件事情,
第一: 判断队列是否为空,这个我想大家都知道。
第二: 将head头指针向后移动一位,返回head移动前的元素,时间复杂度为O(1)。
3:入队
这个跟”出队“的思想相反,同样也是需要做两件事情。
第一:判断队列是否已满。
第二:将tail指针向后移动一位,时间复杂度为O(1)
4: 获取队头
知道”出队“和”入队“的原理,相信大家都懂的如何进行”获取队头“操作,唯一不一样的就是
他是只读操作,不会破坏”队列“结构,时间复杂度为O(1)。
5: 获取队长
大家都知道,我们是用数组来实现队列,所以千万不要想当然的认为数组长度是XXX,
我们维护的是一个head和tail的指针,所以长度自然就是tail-head咯,时间复杂度为O(1)。
三:顺序队列的缺陷
假溢出:
四:循环队列 ,后续再讲
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#define ALLOC_SIZE 512
typedef int KEY_TYPE;
typedef struct _queue_node {
struct _queue_node *next;
KEY_TYPE key;
} queue_node;
typedef struct _queue {
queue_node *front;
queue_node *rear;
int queue_size;
} queue;
void init_queue(queue *q) {
q->front = q->rear = NULL;
q->queue_size = 0;
}
void destory_queue(queue *q) {
queue_node *iter;
queue_node *next;
iter = q->front;
while (iter) {
next = iter->next;
free(iter);
iter = next;
}
}
void push_queue(queue *q, KEY_TYPE key) {
assert(q);
if (q->rear) {
queue_node *node = (queue_node*)calloc(1, sizeof(queue_node));
assert(node);
node->key = key;
node->next = NULL;
q->rear->next = node;
q->rear = node;
} else {
queue_node *node = (queue_node*)calloc(1, sizeof(queue_node));
assert(node);
node->key = key;
node->next = NULL;
q->front = q->rear = node;
}
q->queue_size ++;
}
void pop_queue(queue *q, KEY_TYPE *key) {
assert(q);
assert(q->front != NULL);
if (q->front == q->rear) {
*key = q->front->key;
free(q->front);
q->front = q->rear = NULL;
} else {
queue_node *node = q->front->next;
*key = q->front->key;
free(q->front);
q->front = node;
}
q->queue_size --;
}
int empty_queue(queue *q) {
assert(q);
return q->rear == NULL ? 0 : 1;
}
int size_queue(queue *q) {
return q->queue_size;
}
int main() {
queue q;
init_queue(&q);
int i = 0;
for (i = 0;i < 1000;i ++) {
push_queue(&q, i+1);
}
while (empty_queue(&q)) {
KEY_TYPE key;
pop_queue(&q, &key);
printf("%4d", key);
}
destory_queue(&q);
}