数据结构--队列

一、队列是什么

队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。

总结起来两点:

  1. 一种线性表
  2. 添加操作只能在表尾,删除操作在表头(先进先出)

二、实现队列的思路

1.初始化一个空队列

初始化一个大小固定的数组,并将头指针,尾指针都指向下表为0的位置,但其实这种初始化头指针指向的是队首,尾指针指向的是队尾的后一个元素。
数据结构--队列_第1张图片

2.往队列里添加元素

往队列里添加元素,尾指针后移一位。
数据结构--队列_第2张图片
一直添加直到队列满
数据结构--队列_第3张图片
这个时候尾指针已经出现在数组下标外了

3.消费队列元素

每消费一个队列元素,头指针指向的元素出队,并且后移一位
数据结构--队列_第4张图片

再消费两个
数据结构--队列_第5张图片

这个时候我们想往队列里继续添加元素,尾指针后移,然后发现出现了假溢出的情况,因为尾指针无法再向后移动,而队列实际上并没有满,我们又无法继续往队列里添加数据。这个时候其实有两种解决方案。
方案一:我们每消费一个元素,其后面的元素都整体往前移动一位,就像我们生活中排队打饭一样,后面的人都往前挪一挪。但这种方案带来的后果是,带来的时间开销太大,因为基本上要操作所有的元素,所以这种方案不可行。
方案二:尾指针在指向下表为最后一个元素时,再添加元素,如果还有空位,就将尾指针重新指向0,头指针在取到下表数组末尾时,如果前面还有元素,头指针也指向0,这就是我们说的环形队列。

三、实现环形队列

1.环形队列示例图

尾指针重新指向零
数据结构--队列_第6张图片
再添加一个元素
数据结构--队列_第7张图片

连续消费三个元素,如果前面还有元素,头指针也指向0
数据结构--队列_第8张图片
这个时候我们发现那个原来熟悉的队列又回来了。

Acwing 829 模拟队列

理解和感悟

用数组模拟队列,比用数组模拟栈要麻烦一点,因为栈是同一边进同一边出,而队列是尾巴进,脑袋出。

举个栗子

1、先加入一个元素a,那么需要++tt, 就是tt==0, 然后要求a出队,就是hh++, 这时,hh=1, 现在队列为空,hh>tt
2、因为数组的特点,在数组后面增加元素很方便,在头部增加元素很麻烦,所以设计了hh在左,tt在右的策略,出队hh++, 入队++tt
3、使用数组模拟队列的另一个好处,就是可以遍历队列中的每一个数字,这和用数组模拟栈是一样的,这也是STL比不了的。

普通队列解法

#include 

using namespace std;
const int N = 1e5 + 10;
int q[N], hh, tt = -1;
int main() {
    int n;
    cin >> n;
    while (n--) {
        string op;
        cin >> op;
        if (op == "push") cin >> q[++tt];
        else if (op == "empty")
            hh > tt ? cout << "YES" << endl : cout << "NO" << endl;
        else if (op == "query")
            cout << q[hh] << endl;
        else hh++;
    }
    return 0;
}

循环队列解法

#include 

using namespace std;
const int N = 1e5 + 10;
int q[N], hh, tt;
int main() {
    int n;
    cin >> n;
    while (n--) {
        string op;
        cin >> op;
        if (op == "push") {
            cin >> q[tt++];
            if (tt == N) tt = 0; // 加冒了,就回到0
        } else if (op == "empty")
            hh == tt ? cout << "YES" << endl : cout << "NO" << endl;
        else if (op == "query")
            printf("%d\n", q[hh]);
        else {
            hh++;
            if (hh == N) hh = 0; // 加冒了,就回到0
        }
    }
    return 0;
}

你可能感兴趣的:(【信奥赛之路,2】--,算法基础,数据结构,青少年编程,c++)