一、队列的概念
首先,队列是一种受限制的顺序表。
因为顺序表可以从一串数据中的任意一个位置进行增减操作。
而队列受限的意思是:队列只能从队头来删除数据(出队),从队尾来增加数据(入队)。
它并不像顺序表那样操作灵活。
二、初始化队列
首先,队列再内存中的存储方式也是连续的一片空间,这和顺序表,栈数据结构的存储方式一样。
不同的是,队列有两个int类型的数据,起到指针的作用,其中一个指向队头,另一个指向队尾。
回顾栈,栈中只有一个int类型的起到指针的作用的数据,始终指向栈尾。
如图所示:
所以,队列的初始化代码如下:
#define MAX 10
typedef struct {
int data[MAX];
int front, rear;
}s;
int main()
{
s s1;
s1.front = s1.rear = 0;
return 0;
}
三、队列的入队操作
既然规定队列只能从队尾插入数据,那么在入队操作时,只有int rear 进行一系列操作。
因为初始化队列时,让rear和front都指向了0;此时并没有数据,也可以看成已有数据的后面的又一个位置。所以在进行入队操作时,是让数据插入到rear指向的位置,然后让rear+1往上以一个位置。(这里往上移一个位置会有一些问题)
代码如下:
int main()
{
s s1;
s1.front = s1.rear = 0;
int x = 10;//假设这是要插入的数据
s1.data[s1.rear] = x;//先赋值
s1.rear = s1.rear + 1;//再+1
//也可以写成s1.data[s1.rear++] = x;
return 0;
}
上面说往上移一位会出现一些问题
看下面图:
如果此时,再想添加一个数据,还是在a[9]的上面添加吗?
肯定不是。
因为我们定义的这片空间最高的位置就是data[9].
这时候我们会有一个取模操作。
代码如下:
int main()
{
s s1;
s1.front = s1.rear = 0;
int x = 10;//假设这是要插入的数据
s1.data[s1.front] = x;//先赋值
s1.front = (s1.front + 1)%MAX;//再+1
//也可以写成s1.data[s1.front++] = x;
return 0;
}
因为此时rear=9 +1 之后 rear=10 取模之后变成0 ,就指向了最下面一个位置。这时候就构成了闭环。
如下图所示:
这里的10相当于MAX,为了更好的理解,用MAX=10来举例子
你会发现,10后面的数取模后,就会映射为【0,9】这个范围之内。
这样就相当于一个环形:
四、队列的出队操作
出队操作是在对头进行一系列操作,所以是front进行一系列的减操作。rear不发生变化
代码如下:
int main()
{
s s1;
s1.front = s1.rear = 0;
//中间进行了一系列入队,出队操作。
s1.front = s1.front + 1;
return 0;
}
这里再逻辑上让头指针+1,往后移一位,实际上其位置上的数据并没有删除。
五、队列的判空、满
在初始化时,我们创建了一个空的队列,此时front和rear豆等于0.
那么我们是否可以把条件 front==rear作为判空条件呢?
其实这里也存在一些问题。
我们思考一种极端情况:
a[0]到a[8]都有数据,此时我们再插入一个数据到a[9]。
这时候我们根据上面的取模操作构成闭环后 rear=0了 此时rear==front ,但是此时队列并不是空列表。
那么,到底怎么做能表示队列为空呢?
这时候分两种情况:
① 牺牲一个位置,并且 (rear+1)%MAX==front
如图:
根据上面的极端情况,我们写如下代码:
int main()
{
s s1;
s1.front = s1.rear = 0;
//中间进行了一系列入队,出队操作。
if ((s1.rear + 1) % MAX == s1.front)
{
;//此时判断已满,退出入队操作
}
return 0;
}
②不牺牲位置,增加一个变量,让判断条件更加灵活
这里添加一个变量又分为两种情况:
第一种:添加的变量用来表示数据的个数
代码如下:
typedef struct {
int data[MAX];
int front, rear;
int num;
}s;
int main()
{
s s1;
//进行入队操作
s1.num++;
//进行出队操作
s1.num--;
//判断是否空满
if (s1.num == 10)
{
//判断队列已满
}
return 0;
}
第二种:添加的变量用来表示最后一次操作是入队操作还是出队操作
因为只有入队操作才可能导致队列为满,只有出队操作才可能导致队列为空。
当变量表示入队时,在这种条件下,如果数据的数量==10,则队列为满
当变量表示出队时,在这种条件下,如果数据的数量==0 ,则队列为空
那么这时候怎么表示数据的个数呢?
还是用num++ num--吗?
这时候有一个固定公式:
(rear+MAX-front)%MAX ==数据的个数
代码如下:
typedef struct {
int data[MAX];
int front, rear;
int tag;
}s;
int main()
{
s s1;
s1.tag = 0;//0 代表出队操作
//下面进行入队操作
s1.tag = 1;
if (s1.tag == 1 && (s1.rear + MAX - s1.front) % MAX == 10)
{
;//此时为满
}
//下面进行出队操作
if (s1.tag = 0 && (s1.rear + MAX - s1.front) % MAX == 0)
{
;//此时为空
}
return 0;
}