当前位置: 首页 > article >正文

数据结构 队列

目录

前言

一,队列的基本知识

二,用数组实现队列

三,用链表实现队列

总结


前言

接下来我们将学习队列的知识,这会让我们了解队列的基本概念和基本的功能


一,队列的基本知识

        (Queue)

我们先来研究队列的ADT,ADT这个概念我们再数据结构引论就已经知道ADT是什么东西了,总的来说我们先学习队列操作和特征

队列的特征

队列就跟上面的人排队一样,所以它就有一个自己的简称,First  In  First  Out(先进先出)
所以队列就有一个简称叫FIFO

队列的功能

栈都是再栈顶进行操作的,但是队列是再对头和对尾进行操作的

队列的基本功能:

插入push or EnQueue
删除pop or DeQueue 
返回头部front or peek
检查是否为空IsEmpty
检查是否满员IsFull

C++中插入和删除为push和pop                               C#中的插入和删除为EnQueue和DeQueue 

队列对于功能的要求

插入队尾进行操作  push=enQueue
删除对头进行操作  pop=DeQueue

这就可以参考上面的图,就是人都是队头出来的,所以队列也是一样的,删除从队列的头删除,当我们要插入的时候,就好比如队伍,我们插入是从对尾来的,所以队列也同理可得

队列的抽象视图

队列的应用

说明

我们往往都会有共享资源,但是对于用这些共享资源,我们需要进行服务请求,对于这个请求,我们可能同时又很多个,所以我们可以运用队列这个数据结构,让这些请求进行排队,每一次处理只可以处理一个请求,这样就会做的十分又条理,先来的先享受服务

实例

计算机的处理器就是一个共享资源,很多很多的程序或者说是进程需要处理器的时间片处理的,处理器每次只可以对一个进程进行服务,处理器用来执行指令,算术,和逻辑运算

补充:处理器的时间片是什么呢?

计算机里面的处理器时间片是把进程里面的每一个东西细分化,就比如:我的电脑是边听歌边打游戏的,我的电脑处理器会把这个进程细分化,比如我游戏角色正在跳跃,我们处理器就会处理游戏的跳跃,然后再取处理音乐,这个时间非常短,所以使用者是感受不到的,这个就是处理器的时间片

 

二,用数组实现队列

ADT

Feature

Opearations

1,EnQueue     2,DeQueue     3,Front     4,IsEmpty——————————O(1)

数组

Implementation

#include<iostream>
#include<queue>

using namespace std;

int A[10];
int rear = -1;
int front = -1;

bool IsEmpty();
void EnQueue(int x);

int main() 
{
	
}

bool IsEmpty() {
	if (front == -1 && rear == -1) {
		return false;
	}
	else {
		return true;
	}
}

void EnQueue(int x) {
	if (rear == size(A) - 1) {
		cout << "Queue is full" << endl;
		return;
	}
	else if (IsEmpty()) {
		front = 0;
		rear = 0;
	}
	else {
		rear = rear + 1;
	}
	A[rear] = x;
}

void DeQueue() {
	if (IsEmpty()) {
		return;
	}
	else if (rear == front) {
		front = rear = -1;
	}
	else {
		front = front + 1;
	}
}

int front1(){
	return A[front];
}

这里是实现这个队列的,十分的简单,但是这个数组到最后都没了,前面全部都是空的,那我们要利用好前面的,所以我们来一个循环数组

这样的就是循环数组,我们只需这么改

#include<iostream>
#include<queue>

using namespace std;

int A[10];
int rear = -1;
int front = -1;

bool IsEmpty();
void EnQueue(int x);

int main() 
{
	
}

bool IsEmpty() {
	if (front == -1 && rear == -1) {
		return false;
	}
	else {
		return true;
	}
}

void EnQueue(int x) {
	if ((rear+1)%10 == front) {
		cout << "Queue is full" << endl;
		return;
	}
	else if (IsEmpty()) {
		front = 0;
		rear = 0;
	}
	else {
		rear = (rear + 1) % 10;
	}
	A[rear] = x;
}

void DeQueue() {
	if (IsEmpty()) {
		return;
	}
	else if (rear == front) {
		front = rear = -1;
	}
	else {
		front = (front + 1) % 10;
	}
}

int front1(){
	return A[front];
}

 

三,用链表实现队列

#include <iostream>
using namespace std;

// 队列节点结构
struct Node {
    int data;
    Node* next;
    Node(int val) : data(val), next(nullptr) {}
};

// 链表实现的队列
class Queue {
private:
    Node* frontNode; // 头指针
    Node* rearNode;  // 尾指针
public:
    Queue() : frontNode(nullptr), rearNode(nullptr) {}
    
    // 判断队列是否为空
    bool isEmpty() {
        return frontNode == nullptr;
    }
    
    // 入队操作
    void enqueue(int val) {
        Node* newNode = new Node(val);
        if (isEmpty()) {
            frontNode = rearNode = newNode;
        } else {
            rearNode->next = newNode;
            rearNode = newNode;
        }
    }
    
    // 出队操作
    void dequeue() {
        if (isEmpty()) {
            cout << "Queue is empty!" << endl;
            return;
        }
        Node* temp = frontNode;
        frontNode = frontNode->next;
        delete temp;
        if (frontNode == nullptr) {
            rearNode = nullptr; // 如果队列为空,尾指针也置空
        }
    }
    
    // 获取队头元素
    int front() {
        if (isEmpty()) {
            cout << "Queue is empty!" << endl;
            return -1; // 返回一个错误值
        }
        return frontNode->data;
    }
    
    // 析构函数,释放所有节点
    ~Queue() {
        while (!isEmpty()) {
            dequeue();
        }
    }
};

int main() {
    Queue q;
    q.enqueue(10);
    q.enqueue(20);
    q.enqueue(30);
    
    cout << "Front: " << q.front() << endl; // 输出 10
    
    q.dequeue();
    cout << "Front after dequeue: " << q.front() << endl; // 输出 20
    
    q.dequeue();
    q.dequeue();
    q.dequeue(); // 额外出队,测试空队列情况
    
    return 0;
}

或者头插法与尾插法,这个尾插法我们升级一下用这个指针指向尾巴这样就可以让两个时间复杂度都是O(1)


总结

这个队列十分简单真的,就是头出尾进罢了


http://www.kler.cn/a/525947.html

相关文章:

  • 你好!这是我自己的CSDN博客!
  • dify实现原理分析-rag-检索(Retrieval)服务的实现
  • 全面解析文件上传下载删除漏洞:风险与应对
  • 【最后203篇系列】007 使用APS搭建本地定时任务
  • 快速分析LabVIEW主要特征进行判断
  • Spring Boot - 数据库集成05 - 集成MongoDB
  • 深度大数据:从数据洪流到智能决策的革命性跨越
  • php接口连接数据库
  • 【狂热算法篇】探秘图论之Dijkstra 算法:穿越图的迷宫的最短路径力量(通俗易懂版)
  • Vue3的el-table-column增加跳转其他页面
  • 模型I/O功能之模型包装器
  • LeetCode题练习与总结:最长和谐子序列--594
  • 反向代理模块b
  • CF 764B.Timofey and cubes(Java实现)
  • 【Rust自学】17.2. 使用trait对象来存储不同值的类型
  • Java内存模型 volatile 线程安全
  • 为AI聊天工具添加一个知识系统 之71 详细设计 之12 形式文法、范式语法和惯式用法
  • 2024 ICLR Spotlight Learning-Feedback
  • 网络攻防实战指北专栏讲解大纲与网络安全法
  • C语言练习(32)
  • C++,STL,【目录篇】
  • Formality:黑盒(black box)
  • 基于RAG方案构专属私有知识库(开源|高效|可定制)
  • oracle中使用in 和 not in 查询效率分析
  • 控件【QT】
  • 对于RocksDB和LSM Tree的一些理解