队列这个数据结构的逻辑实现(定义)可以说是十分好理解的,为什么这么讲呢,因为身为文明现代社会的我们肯定都排过队,排队的时候先到先得这个道理我么大家都知道,所以我们在队这种抽象数据结构的逻辑实现就是按照这种所谓的FIFO(first in first out)的方式来实现的。
其实一开始应该说基操的,但是“基操”都有啥这个事情,身为小学生都应该知道的:创销增删改查空,是啥意思我就不用多介绍了,下面就开始说一一来说这些基操物理实现(这里是C语言实现其他语言的实现后续会写)。
首先就得说创、增、删也就是开辟动态内存、入队、出队,为什么我要西安说这个呢应为这里会说到几个很有趣的点,也就是出队的时候的细节。
首先,按照顺序来先说‘创’,你去一家爆火的餐厅吃饭(比如济南的xxx、ps:菜贼难吃、人还多),然后老板说排号,然后给你了一个号码,你一看我勒个天,这大长溜人,你想知道这个啥时候能吃上饭,你不得问老板:老板大概还有多久能吃上。然后老板看看你不屑地回答道:“你这一个号大概得20分钟,那你看这一共30个人排队,最后一个是你”你一看好家伙这老板在饭店入口蹲着查人都大汗淋漓的,我这不得晒成柴火干,然后你问站你旁边的女朋友“:咱有啥法能快点吃上饭白?”她看着你平静的说“:你的目的是吃那个餐车上做好的菜,那很简单我这里有两种办法,一个是你让你前面的人往前走等到他们都走完了轮到你了你就吃上了,还有一个办法是:你闯进去把餐车推出来我在这里等你。”你一看这好家伙,前面这么多人,身为文明社会的好公民要遵纪守法,我的素质怎么允许我闯进去,你正在那里犯嘀咕的时候,突然旁边的透明橱窗响起了咚咚咚敲玻璃声,你正想转头对着橱窗说这是谁家小孩,你一看啊呀,这不是七大姑小姨她三舅的六弟的儿子吗,你俩小时候还一块用尿和泥巴玩得,他喊了一下你的名字就出来了,你俩寒暄几句,旁边女朋友看你跟个二傻子的似的啥也不说,他帮你问到:“弟弟,你也在这个饭店吃饭呢?”你这七大姑小姨她三舅的六弟的儿子赶忙说到“:嫂子,我在这里做大厨,后厨归我管,刚才有个客人说咱有个菜不太行我就过去调解了下,你跟哥你俩是干啥去。”你一听到这个好家伙,赶忙抢话说“弟来,我跟你嫂子就是想在你这个馆子吃饭,你看你家生意太好了,俺俩就想着去旁边喝碗面条算了。”六弟他儿子赶紧拉着你说“走哥来,你能来我馆子吃饭是弟弟的荣幸,今天必须给你安排了。”然后你边推开他的手边说“你看你这里那么忙,我就不给你添麻烦了,改天再过来,咱俩好好聚聚。”六弟他儿子拽着你说说:“赶紧哥来,多少都是弟弟一片心意,你要是这点面子都不给你弟弟你是看不起我。”推脱间你弟说“既然俺哥不太愿意,我就让后厨把菜端出来外面有桌子也安静。”你推脱着说:“六弟你这话确实在理,但是你哥不想给你添麻烦,你赶紧忙你的去吧,赶紧去吧。”说话间老板便让后厨把菜端出来了客气的说“哥来,咱不知道是自己家人,这样这顿算我勒,好吃哥哥常来就是我最大的荣幸。”你跟老板和你弟又寒暄了几十句,就各忙各的去了(当然人家是忙事,你是忙吃)。
上面我写的这个故事不知道读完之后有什么感想和启发,这里面有有关队列要素和判断队列是否为空的方法下面我一一说明:
上面故事的每个号大概20分钟就是指队数组的每个元素所占字节大小(也就是你用malloc开辟的内存),有几个人(就是队的长度),排号排到哪里了也就是故事里取号在最后的你(队尾标志),饭店的餐车(队头),出队的方法也对应有故事里的两种一个是元素移动(老老实实排队等着和你遇到七大姑小姨她三舅的六弟的儿子时老板把餐车给你推出来,这两件事哪个完成了都相当于你这个元素出队了,当然我们非常不提倡后者这只是笔者杜撰的一个故事,说到底就是所谓的元素出队就是相对队头指针(队头标志)位置在前也就是对头在你屁股后面的时候你就出队了,那入队呢?入队很简单我们只需要找到队尾然后在他屁股后面放个人(数据)就行了,前提是队尾的屁股后面要有地方站人不能是个悬崖啥的(也就是要开辟内存用于数据的存放),下面是笔者画的图释和对应的C源码:
//
// main.c
// Queeue_using_Array
//
// Created by 郭宸羽 on 3/8/2022.
//
#include <stdio.h>
#include <stdlib.h>
typedef struct Queue
{
int size;
int front;
int rear;
int *Q;
}Queue;
void create(Queue *q,int size)
{
q->size = size;
q->front = -1;
q->rear = -1;
q->Q = (int*)malloc(sizeof(int)*size);
}
int Enqueue(Queue *q,int data)
{
if(q->rear == q->front && q->rear != -1 && q->front != -1)
{
printf("This queue is empty, please create new queue.\n");
return -1;
}
else if(q->rear+1 == q->size)
{
printf("The queeue has full\n");
return -1;
}
else
{
q->rear++;
q->Q[q->rear] = data;
return 1;
}
}
int Dequeue(Queue *q)
{
int dequeue_data;
if(q->rear == q->front)
{
printf("This queue is empty\n");
return -1;
}
else
{
q->front++;
dequeue_data = q->Q[q->front];
printf("Dequeue data is %d\n",dequeue_data);
return 1;
}
}
void Display(Queue q)
{
for(int i = q.front + 1;i <= q.rear;i++)
{
printf("[%d-]-",q.Q[i]);
}
printf(".......\n");
}
int main()
{
Queue q1;
create(&q1, 6);
Enqueue(&q1, 3);
Enqueue(&q1, 31);
Enqueue(&q1, 32);
Enqueue(&q1, 33);
Enqueue(&q1, 34);
Enqueue(&q1, 35);
Enqueue(&q1, 36);
Display(q1);
Dequeue(&q1);
Dequeue(&q1);
Dequeue(&q1);
Dequeue(&q1);
Dequeue(&q1);
Dequeue(&q1);
Dequeue(&q1);
}