队列C++实现

基本概念

定义

一种操作受限的线性表,只允许在表的一段进行插入,而在表的另一端进行删除。向队列中插入元素称为入队或进队;删除元素称为出队或离队。最早排队的也是最早离队的,操作的特性就是先进先出,也就是FIFO。

队头(Front)。允许删除的一端,又称为队首。

队尾(Rear)。允许插入的一端。

空队列。不凡任何元素的空表。

队列常见的基本操作

InitQueue (&Q); 初始化队列,构造一个空队列Q

QueueEmpty(Q); 判断列空,若队列Q为空返回true,否则返回false

EnQueue (&Q , x); 入队,若队列Q未满,将x加入,使之成为新的队尾

DeQueue (&Q , &x); 出队,若队列Q非空,删除队头元素,并用x返回

GetHead (Q , &x); 读取队头元素,若队列Q非空,则将队头元素赋值给x

注:栈和队列是操作受限的线性表,因此不是任何对线性表的操作都可以作为栈和队列的操作。比如,如可以随便读取栈或队列中间的某个数据。

队列的顺序存储结构

存储类型描述以及基本操作的代码如下:

//
// Created by PrimeChuJiang on 2022/11/22.
//
#include <iostream>

#define Maxsize 50

using namespace std;

typedef struct {
    int data[Maxsize];
    int front ;
    int rear ;
}SqQueue;

void InitQueue(SqQueue &Q){
    Q.front = 0;
    Q.rear = 0;
}

bool QueueEmpty(SqQueue Q){
    return Q.rear == Q.front;
}

bool QueueOverflow(SqQueue Q){
    return (Q.rear+1)%Maxsize == Q.front;
}

void EnQueue(SqQueue &Q , int x){
    if (QueueOverflow(Q)) {
        cout<<"WARNING: List is full!"<<endl;
        return;
    }
    Q.data[Q.rear] = x;
    Q.rear = (Q.rear+1)%Maxsize;
}

void DeQueue(SqQueue &Q , int & x){
    if (QueueEmpty(Q)){
        cout<<"WARNING:List is empty!"<<endl;
        return;
    }
    x = Q.data[Q.front];
    Q.front = (Q.front+1)%Maxsize;
}

void GetHead (SqQueue Q , int &x){
    x = Q.data[Q.front];
}

int main(){
    SqQueue Q;
    int x;
    bool flag;
    InitQueue(Q);
    flag = QueueEmpty(Q);
    EnQueue(Q,1);
    GetHead(Q,x);
    EnQueue(Q,2);
    EnQueue(Q,3);
    EnQueue(Q,4);
    EnQueue(Q,5);
    EnQueue(Q,6);
    GetHead(Q,x);
    flag = QueueEmpty(Q);
    DeQueue(Q,x);
    cout<<x<<endl;
    DeQueue(Q,x);
    cout<<x<<endl;
    DeQueue(Q,x);
    cout<<x<<endl;
    DeQueue(Q,x);
    cout<<x<<endl;
    DeQueue(Q,x);
    cout<<x<<endl;
    DeQueue(Q,x);c
    cout<<x<<endl;
}

队列的链式存储结构

存储类型描述以及基本操作的代码如下:

//
// Created by Administrator on 2022/11/22.
//
#include <cstring>

using namespace std;

typedef struct LNode{
    int data;
    struct LNode * next;
}LNode;

typedef struct LinkQueue{
    LNode * rear;
    LNode * front;
}LinkQueue;

void InitQueue(LinkQueue & Q){
    Q.rear = Q.front = new LNode ;
}

bool QueueEmpty(LinkQueue &Q){
    return Q.front == Q.rear;
}

//链式存储不存在上溢问题,就不用QueueOverflow函数

void EnQueue(LinkQueue &Q , int x){
    auto * s = new LNode ;
    s->data = x;
    s->next = Q.rear->next;
    Q.rear->next = s;
    Q.rear = s;
}

void DeQueue(LinkQueue &Q , int & x){
    LNode * p = Q.front->next;
    Q.front->next = p->next;
    x = p->data;
    if(p==Q.rear){
        Q.rear = Q.front;
    }
    operator delete(p);
}

void GetHead (LinkQueue Q , int &x){
    x = Q.rear->data;
}
c
int main (){

}

双端队列

双端队列是指允许两端都可以进行入队和出队操作的队列。其元素的逻辑结构仍然是线性结构。队列的两端都可以入队和出队。题目一般给定一个输入序列或输出序列,问四个选项的哪一个选项是不能由双端队列得到的,我们只需要根据受限的一端逆推就行了。

<think>好的,用户想了解如何用C++实现队列数据结构,需要示例代码或教程。首先,我需要回忆队列的基本概念,队列是FIFO结构,支持入队和出队操作。常见的实现方式有数组和链表。 接下来,查看用户提供的引用内容。引用[1]和[3]提到了队列C++实现,特别是引用[3]中有一个顺序队列的示例代码。不过,用户提供的引用中的代码可能存在格式问题,比如使用了&这样的HTML实体,需要转换为&符号。此外,引用中的代码可能使用了C风格的函数指针,而C++中更常用类来封装数据结构。 用户需要的是清晰的示例代码和教程步骤。因此,我应该分步骤讲解,首先用数组实现循环队列,然后用链表实现。循环队列需要注意队满和队空的判断条件,通常通过预留一个位置或者使用计数器来解决。链表实现则更灵活,无需担心容量问题。 还需要注意代码的现代C++风格,比如使用类模板、智能指针等,但考虑到用户可能更倾向于基础实现,先提供结构化的类实现,再考虑模板化。同时,要确保代码的正确性,比如指针操作、内存管理等。 最后,生成相关问题,帮助用户深入理解队列的应用和扩展,比如性能优化、线程安全等。需要确保问题与队列相关,并且能够引导用户进一步学习。</think>### C++队列实现详解 队列是先进先出(FIFO)的线性数据结构,包含入队(enqueue)和出队(dequeue)两个基本操作[^1]。以下是两种常见的实现方式: #### 一、数组实现(循环队列) ```cpp #include <iostream> using namespace std; const int MAX_SIZE = 5; class ArrayQueue { private: int data[MAX_SIZE]; int front; int rear; public: ArrayQueue() : front(0), rear(0) {} bool enqueue(int value) { if ((rear + 1) % MAX_SIZE == front) { // 队满判断 cout << "队列已满!" << endl; return false; } data[rear] = value; rear = (rear + 1) % MAX_SIZE; return true; } bool dequeue() { if (front == rear) { // 队空判断 cout << "队列为空!" << endl; return false; } front = (front + 1) % MAX_SIZE; return true; } int getFront() { if (front == rear) return -1; return data[front]; } }; // 使用示例 int main() { ArrayQueue q; q.enqueue(10); q.enqueue(20); cout << "队首元素:" << q.getFront() << endl; q.dequeue(); cout << "新队首:" << q.getFront() << endl; return 0; } ``` 关键点说明: 1. 使用模运算实现循环队列,解决假溢出问题 2. 队满条件:$(rear+1)\%MAX\_SIZE == front$ 3. 队空条件:$front == rear$[^3] #### 二、链表实现 ```cpp #include <iostream> using namespace std; struct Node { int data; Node* next; Node(int val) : data(val), next(nullptr) {} }; class LinkedListQueue { private: Node* front; Node* rear; public: LinkedListQueue() : front(nullptr), rear(nullptr) {} void enqueue(int value) { Node* newNode = new Node(value); if (rear == nullptr) { front = rear = newNode; return; } rear->next = newNode; rear = newNode; } void dequeue() { if (front == nullptr) return; Node* temp = front; front = front->next; if (front == nullptr) rear = nullptr; delete temp; } int getFront() { return front ? front->data : -1; } }; ``` ### 实现步骤解析 1. **初始化**:设置队首和队尾指针 2. **入队操作**: - 数组实现:检查队列是否已满,更新rear指针 - 链表实现:创建新节点,更新尾部指针 3. **出队操作**: - 数组实现:移动front指针 - 链表实现:释放头节点内存,更新front指针 4. **边界处理**: - 数组实现需处理循环逻辑 - 链表实现需处理空队列情况 ### 性能对比 | 实现方式 | 时间复杂度 | 空间利用率 | 适用场景 | |----------|------------|------------|----------| | 数组 | O(1) | 固定容量 | 已知最大容量 | | 链表 | O(1) | 动态扩展 | 频繁插入删除 |
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

楚江_wog1st

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值