STL之queue 【队列】

queue:队列,先进先出(FIFO)的数据结构。

一.基本用法

1.头文件

#include <queue>

2.创建queue

你可以创建一个 std::queue 对象,并将其绑定到其他容器(通常是 deque或 list)以提供队列的功能:

std::queue<int> myQueue;  // 创建一个整数类型的队列

3.插入元素:

myQueue.push(42);
myQueue.push(17);

4.删除元素(弹出元素):

myQueue.pop();  // 弹出队列前端元素

5.访问队列的前端元素

使用 front 函数访问队列的前端元素,但不会从队列中移除它:

int frontElement = myQueue.front();  // 访问队列前端元素

6.访问队列的后端元素

使用 back 函数访问队列的后端元素,但不会从队列中移除它:

int backElement = myQueue.back();  // 访问队列后端元素

7.检查队列是否为空

使用 empty 函数检查队列是否为空:

if (myQueue.empty()) {
    std::cout << "Queue is empty." << std::endl;
} else {
    std::cout << "Queue is not empty." << std::endl;
}

8.获取队列的大小

使用 size 函数获取队列的大小:

size_t queueSize = myQueue.size();  // 获取队列的大小

二.综合示例:

#include <iostream>
#include <queue>

int main() {
    std::queue<int> myQueue;

    myQueue.push(42);
    myQueue.push(17);

    int frontElement = myQueue.front();
    std::cout << "Front element: " << frontElement << std::endl;

    myQueue.pop();

    int backElement = myQueue.back();
    std::cout << "Back element: " << backElement << std::endl;

    if (myQueue.empty()) {
        std::cout << "Queue is empty." << std::endl;
    } else {
        std::cout << "Queue is not empty." << std::endl;
    }

    return 0;
}

用C语言实现队列queue

#include <stdio.h>
#include <stdlib.h>

// 定义队列节点
typedef struct Node {
    int data;
    struct Node* next;
} Node;

// 定义队列
typedef struct {
    Node* front; // 队头指针
    Node* rear;  // 队尾指针
} Queue;

// 初始化队列
void initializeQueue(Queue* queue) {
    queue->front = NULL;
    queue->rear = NULL;
}

// 判断队列是否为空
int isEmpty(Queue* queue) {
    return queue->front == NULL;
}

// 入队操作
void enqueue(Queue* queue, int value) {
    Node* newNode = (Node*)malloc(sizeof(Node));
    newNode->data = value;
    newNode->next = NULL;

    if (isEmpty(queue)) {
        // 如果队列为空,新节点同时成为队头和队尾
        queue->front = newNode;
        queue->rear = newNode;
    }
    else {
        // 否则将新节点链接到队尾,并更新队尾指针
        queue->rear->next = newNode;
        queue->rear = newNode;
    }
}

// 出队操作
int dequeue(Queue* queue) {
    if (isEmpty(queue)) {
        printf("Queue underflow\n");
        return -1; // 表示队列为空
    }

    // 取出队头节点的数据
    int value = queue->front->data;

    // 更新队头指针,如果队列只有一个元素,出队后队列为空
    Node* temp = queue->front;
    queue->front = queue->front->next;
    free(temp);

    // 如果队列变为空,更新队尾指针
    if (queue->front == NULL) {
        queue->rear = NULL;
    }

    return value;
}

// 打印队列元素
void printQueue(Queue* queue) {
    if (isEmpty(queue)) {
        printf("Queue is empty\n");
        return;
    }

    printf("Queue elements: ");
    Node* current = queue->front;
    while (current != NULL) {
        printf("%d ", current->data);
        current = current->next;
    }
    printf("\n");
}

// 释放队列占用的内存
void freeQueue(Queue* queue) {
    while (!isEmpty(queue)) {
        dequeue(queue);
    }
}

int main() {
    Queue myQueue;
    initializeQueue(&myQueue);

    enqueue(&myQueue, 10);
    enqueue(&myQueue, 20);
    enqueue(&myQueue, 30);

    printQueue(&myQueue);

    printf("Dequeued element: %d\n", dequeue(&myQueue));

    printQueue(&myQueue);

    freeQueue(&myQueue);

    return 0;
}

队列

常见的应用场景包括:

  1. 任务调度: 队列可用于任务调度,确保任务按照提交的顺序进行处理。先提交的任务先执行。

  2. 广度优先搜索(BFS): 在图算法中,BFS使用队列来管理待访问的节点,确保按照层级的顺序访问节点。

  3. 打印队列: 在打印系统中,打印任务被排入队列,以便按照先到先服务的原则进行打印。

  4. 缓冲区管理: 队列可以用于管理缓冲区,例如处理网络数据包、操作系统中的缓冲队列等。

  5. 消息传递: 队列常用于实现消息传递系统,其中消息按照发送的顺序进行排队和处理。

  6. 多线程编程: 在多线程应用程序中,队列可以用于线程之间的通信,充当线程安全的消息传递通道。

  7. 实现广告投放系统: 队列可以用于按照广告请求的先后顺序管理广告投放任务。

  8. 计算机网络中的数据传输: 在网络通信中,数据包通常以队列的形式进行传输,确保按照发送的顺序接收。

  9. 作业调度: 在操作系统中,队列可用于作业调度,确保作业按照提交的先后顺序执行。

  10. 排队系统: 在实际生活中的排队系统,如银行、超市等,顾客按照先来先服务的原则排队。

场景示例:BFS

广度优先搜索(Breadth-First Search,BFS)是一种图算法,用于遍历或搜索图数据结构中的所有节点,同时按照层级顺序访问它们。BFS从图中的某一节点开始,首先访问该节点,然后逐层访问其相邻节点,确保先访问离起始节点最近的节点。

BFS的基本思想是使用队列数据结构来辅助实现层级遍历。具体步骤如下:

  1. 将起始节点放入队列中。
  2. 从队列中取出一个节点,并访问该节点。
  3. 将该节点的未访问邻居节点加入队列。
  4. 重复步骤2和步骤3,直到队列为空。

BFS保证了从起始节点开始,逐层遍历到离起始节点最远的节点。这使得BFS在解决一些问题时具有特殊的优势,例如找到最短路径、检测图中的环等。

BFS

#include <stdio.h>
#include <stdbool.h>

#define MAX_VERTICES 6

//定义图结构
typedef struct {
    int vertices[MAX_VERTICES][MAX_VERTICES];//存储节点之间连接关系
    int numVertices;//存储节点数量
} Graph;

//初始化图,所有元素默认值0,表示初始状态下没有边相连
void initializeGraph(Graph* graph, int numVertices) {
    graph->numVertices = numVertices;

    for (int i = 0; i < numVertices; ++i) {
        for (int j = 0; j < numVertices; ++j) {
            graph->vertices[i][j] = 0;
        }
    }
}

//addEdge 函数用于向图中添加一条边,这里是无向图,设置值为1表示有边
void addEdge(Graph* graph, int start, int end) {
    graph->vertices[start][end] = 1;
    graph->vertices[end][start] = 1;
}

void bfs(Graph* graph, int startVertex) {
    int visited[MAX_VERTICES] = { 0 };//用于记录节点是否被访问过
    int queue[MAX_VERTICES];//用于按照层级顺序存储待访问的节点
    int front = 0, rear = -1;

    visited[startVertex] = 1;
    queue[++rear] = startVertex;

    while (front <= rear) {
        int currentVertex = queue[front++];
        printf("Visited vertex: %d\n", currentVertex);

        for (int i = 0; i < graph->numVertices; ++i) {
            if (graph->vertices[currentVertex][i] == 1 && !visited[i]) {
                visited[i] = 1;
                queue[++rear] = i;
            }
        }
    }
}

int main() {
    Graph graph;
    initializeGraph(&graph, MAX_VERTICES);

    addEdge(&graph, 0, 1);
    addEdge(&graph, 0, 2);
    addEdge(&graph, 1, 3);
    addEdge(&graph, 1, 4);
    addEdge(&graph, 2, 5);

    printf("BFS starting from vertex 0:\n");
    bfs(&graph, 0);

    return 0;
}

关注我,为大家持续分享更多的内容,让学习变得更简单,与君共勉,共同成长。 也可以关注我的公众号CoderSong,查看更多精彩文章

  • 13
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

西里小诸葛

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

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

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

打赏作者

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

抵扣说明:

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

余额充值