写在前面:
今天我们来学习一下队列结构,这也是我们讲线性表的最后一个部分了,这里会分成两节来讲,先讲数组的实现,再讲链表的实现。由于双端队列是包含了单端队列的操作,所以我们这里为了讲的更全一些,代码实现为双端队列。
队列的定义
我们前面学习栈的时候知道,栈遵循“先进后出”的原则,而队列则不一样,它遵循“先进先出”的原则,也就是从尾部进去,从头部出来。这里我们会用到两个指针,具体后面再讲,我们先看实现。
双端队列与单端不同的地方就是不用遵循先进先出原则,它头尾都可以进行插入和删除操作,所以双端操作其实是包含单端操作的代码实现的。
上面分别对应了插入和删除操作,在数组中,我们一般会用左指针和右指针来分别记录我们数据的左边界和右边界。每次插入时,右指针都会右移一位;每次删除时,左指针都会右移一位。
这样我们每次读取数据时就只用读左指针右边和右指针左边的数据即可,但是这可能会浪费很多空间,所以我们可以循环使用,也就是当指针达到左边界或右边界时,指针需要进行调整,接下来我们看看该如何实现。
队列的插入
对于单端队列来说,我们只能从数组的右侧插入数据,那我们就先实现队列的这个功能。
//判断是否为空 int isEmpty() { if (Size == 0) return 1; return 0; } //判断是否已满 int isFull() { if (Size == maxSize) return 1; return 0; } //右插入操作 void right_insert(int key) { //判断队列是否已满 if (isFull()) { cout << "队列已满!" << endl; return; } else { //判断队列是否为空,如果为空初始化左右指针 if (isEmpty()) { Right = Left = 0; Queue[Right] = key; } else { //如果右指针达到了右边界,那要减去最大容量 if (Right == maxSize - 1) { Right = -1; } Queue[++Right] = key; } Size++; } }
既然我们都写好了右插操作,那么左插操作就类似,每次往左边插入时只需将左指针往左移一位即可,这里同样要注意边界问题。
//左插入操作 void left_insert(int key) { if (isFull()) { cout << "队列已满!" << endl; return; } else { if (isEmpty()) { Right = Left = 0; Queue[Left] = key; } else { //如果左指针达到了左边界,那要加上最大容量 if (Left == 0) { Left = maxSize; } Queue[--Left] = key; } Size++; } }
如果你还是不太理解,我们可以看一下左插入和右插入的操作图解:
队列的删除
队列的删除操作与插入操作非常类似,左右指针只用往反方向移动即可。
//右删除操作 void right_delete() { if (isEmpty()) { cout << "队列为空!" << endl; } else { Right--; if (Right == -1) { Right = maxSize - 1; } Size--; } } //左删除操作 void left_delete() { if (isEmpty()) { cout << "队列为空!" << endl; } else { Left++; if (Left == maxSize) { Left == 0; } Size--; } }
每次进行删除操作时我们不用将删除的地方清空,因为每次插入时都会覆盖掉该地方之前的值。
全部代码
#include<bits/stdc++.h> using namespace std; int* Queue; //队列 int Right; //右指针 int Left; //左指针 int Size; //队列的大小 int maxSize=5; //默认最大数量为5 int isEmpty(); //判断队列是否为空 int isFull(); //判断队列是否已满 void right_insert(int); //队列的右插入 void left_insert(int); //队列的左插入 void right_delete(); //队列的右删除 void left_delete(); //队列的左删除 void show(); //输出队列数据 int main() { Queue = new int[maxSize]; right_insert(1); left_insert(2); right_insert(3); left_insert(4); show(); left_delete(); right_delete(); show(); delete[]Queue; } //输出队列内容 void show() { if (isEmpty()) { cout << "队列为空!" << endl; } else { int temp = Left; for (int i = 0; i < Size; i++) { cout << Queue[temp] << " "; temp++; if (temp == maxSize) { temp = 0; } } cout << endl; } } //判断队列是否为空 int isEmpty() { if (Size == 0) return 1; return 0; } //判断队列是否已满 int isFull() { if (Size == maxSize) return 1; return 0; } //右插入操作 void right_insert(int key) { //判断队列是否已满,如果已满则不能进行插入操作 if (isFull()) { cout << "队列已满!" << endl; return; } else { //判断队列是否为空,如果为空初始化左右指针 if (isEmpty()) { Right = Left = 0; Queue[Right] = key; } else { //如果右指针达到了右边界,那要减去最大容量 if (Right == maxSize - 1) { Right = -1; } Queue[++Right] = key; } Size++; } } //左插入操作 void left_insert(int key) { if (isFull()) { cout << "队列已满!" << endl; return; } else { if (isEmpty()) { Right = Left = 0; Queue[Left] = key; } else { //如果左指针达到了左边界,那要加上最大容量 if (Left == 0) { Left = maxSize; } Queue[--Left] = key; } Size++; } } //右删除操作 void right_delete() { if (isEmpty()) { cout << "队列为空!" << endl; } else { Right--; if (Right == -1) { Right = maxSize - 1; } Size--; } } //左删除操作 void left_delete() { if (isEmpty()) { cout << "队列为空!" << endl; } else { Left++; if (Left == maxSize) { Left == 0; } Size--; } }
如果大家有什么问题的话,欢迎在下方评论区进行讨论哦~
发表评论