C++实现线性表 - 05 队列(数组实现)

简介: 今天我们来学习一下队列结构,这也是我们讲线性表的最后一个部分了,这里会分成两节来讲,先讲数组的实现,再讲链表的实现。由于双端队列是包含了单端队列的操作,所以我们这里为了讲的更全一些,代码实现为双端队列。
写在前面:
今天我们来学习一下队列结构,这也是我们讲线性表的最后一个部分了,这里会分成两节来讲,先讲数组的实现,再讲链表的实现。由于双端队列是包含了单端队列的操作,所以我们这里为了讲的更全一些,代码实现为双端队列。

队列的定义

我们前面学习栈的时候知道,栈遵循“先进后出”的原则,而队列则不一样,它遵循“先进先出”的原则,也就是从尾部进去,从头部出来。这里我们会用到两个指针,具体后面再讲,我们先看实现。

双端队列与单端不同的地方就是不用遵循先进先出原则,它头尾都可以进行插入和删除操作,所以双端操作其实是包含单端操作的代码实现的。

1.png

2.png

3.png

上面分别对应了插入删除操作,在数组中,我们一般会用左指针和右指针来分别记录我们数据的左边界和右边界。每次插入时,右指针都会右移一位;每次删除时,左指针都会右移一位。
这样我们每次读取数据时就只用读左指针右边和右指针左边的数据即可,但是这可能会浪费很多空间,所以我们可以循环使用,也就是当指针达到左边界或右边界时,指针需要进行调整,接下来我们看看该如何实现。

队列的插入

对于单端队列来说,我们只能从数组的右侧插入数据,那我们就先实现队列的这个功能。

//判断是否为空
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--;
    }
}

如果大家有什么问题的话,欢迎在下方评论区进行讨论哦~

目录
相关文章
|
2月前
|
搜索推荐 编译器 C语言
【C++核心】特殊的元素集合-数组与字符串详解
这篇文章详细讲解了C++中数组和字符串的基本概念、操作和应用,包括一维数组、二维数组的定义和使用,以及C风格字符串和C++字符串类的对比。
80 4
|
18天前
|
缓存 安全 C++
C++无锁队列:解锁多线程编程新境界
【10月更文挑战第27天】
32 7
|
18天前
|
消息中间件 存储 安全
|
2月前
|
C++
C++(十一)对象数组
本文介绍了C++中对象数组的使用方法及其注意事项。通过示例展示了如何定义和初始化对象数组,并解释了栈对象数组与堆对象数组在初始化时的区别。重点强调了构造器设计时应考虑无参构造器的重要性,以及在需要进一步初始化的情况下采用二段式初始化策略的应用场景。
|
3月前
|
算法 C++
c++学习笔记04 数组
这篇文章是C++学习笔记4,主题是数组。
43 4
|
3月前
|
C++ 索引
C++数组、vector求最大值最小值及其下标
C++数组、vector求最大值最小值及其下标
118 0
|
4月前
|
C++ 索引 运维
开发与运维数组问题之在C++中数组名和指针是等价如何解决
开发与运维数组问题之在C++中数组名和指针是等价如何解决
31 6
|
4月前
|
存储 安全 C++
开发与运维数组问题之声明一个数组如何解决
开发与运维数组问题之声明一个数组如何解决
45 6
|
4月前
|
存储 C++ 容器
开发与运维数组问题之C++标准库中提供数据容器作为数组的替代如何解决
开发与运维数组问题之C++标准库中提供数据容器作为数组的替代如何解决
54 5
|
3月前
|
安全 编译器 C语言
C++入门-数组
C++入门-数组