基于数组和链表实现队列

队列

队列是一种遵循先入先出的线性数据结构,它模拟了排队的现象,新来的不断加入队列的尾部,而位于队列头部的依次离开。

我们将队列的头部成为队首,队列的尾部成为队尾。

将元素添加到队列的操作成为入队,将元素删除队列的操作成为出队

队列的常用操作

push():元素入队,时间复杂度O(1)

pop():元素出队,时间复杂度O(1)

peek()访问队首元素,时间复杂度O(1)

//
// Created by Administrator on 2024/1/10.
//
#include "iostream"
#include "queue"

using namespace std;

int main(){
    queue<int> que;
    //元素入队
    cout<<"元素入队1,2,3"<<endl;
    que.push(1);
    que.push(2);
    que.push(3);
    cout<<"访问队首元素:"<<que.front()<<endl;
    cout<<"元素出队:"<<endl;
    que.pop();
    cout<<"访问队首元素:"<<que.front()<<endl;
    cout<<"队列长度:"<<que.size()<<endl;
    cout<<"判断队列是否为空:"<<que.empty()<<endl;
}
//输出结果
元素入队1,2,3
访问队首元素:1
元素出队:
访问队首元素:2
队列长度:2
判断队列是否为空:0

队列的实现

队列需要在两端进行操作,一端执行入队操作,一端执行出队操作,所以,数组和链表都可以满足

基于链表的实现

我们可以将链表的头节点,尾节点分别作为队列的队头和队尾,规定队尾仅可以添加元素,队首仅可以删除元素

//
// Created by Administrator on 2024/1/10.
//
# include "iostream"
#include "vector"

using namespace std;
struct LinkNode{
    int val;
    LinkNode *next;
};

class myQueue{
private:
    LinkNode *front,*rear;
    int queSize;
public:
    myQueue() {
        front = nullptr;
        rear = nullptr;
        queSize = 0;
    }
    //获取队列长度
    int size(){
        return queSize;
    }
    //判断队列是否为空
    bool empty(){
        return queSize==0;
    }
    //入队
    void push(int num){
        LinkNode *temp = new LinkNode;
        temp->val = num;
        if(front == nullptr){
            front = temp;
            rear = temp;
        } else{
            rear->next = temp;
            rear = temp;
        }
        queSize++;
    }
    //访问队首元素
    int peek(){
        if(queSize == 0){
            throw out_of_range("对列为空");
        } else{
            return front->val;
        }
    }
    //出队
    int pop(){
        int temp = peek();
        LinkNode *node  = front;
        front = front->next;
        delete node;
        queSize--;
        return temp;
    }
    /* 将链表转化为 Vector 并返回 */
    vector<int> toVector() {
        LinkNode *node = front;
        vector<int> res(size());
        for (int i = 0; i < res.size(); i++) {
            res[i] = node->val;
            node = node->next;
        }
        return res;
    }
};

int main(){
    cout<<"测试基于链表实现队列"<<endl;
    cout<<"向队列中添加元素1,2,3"<<endl;
    myQueue myque;
    myque.push(1);
    myque.push(2);
    myque.push(3);
    cout<<"获取队首元素:"<<myque.peek()<<endl;
    cout<<"队列元素个数"<<myque.size()<<endl;
    cout<<"队列是否为空?:"<<myque.empty()<<endl;
    cout<<"执行出队操作:"<<endl;
    myque.pop();
    cout<<"获取队首元素:"<<myque.peek()<<endl;
    cout<<"队列元素个数"<<myque.size()<<endl;
    cout<<"此时队列内的元素:"<<endl;
    vector<int> temp = myque.toVector();
    for(int i : temp ){
        cout<<i<<" ";
    }

}
//输出结果
测试基于链表实现队列
向队列中添加元素1,2,3
获取队首元素:1
队列元素个数3
队列是否为空?:0
执行出队操作:
获取队首元素:2
队列元素个数2
此时队列内的元素:
2 3

基于数组的实现

在数组中的首部删除元素的时间复杂度是O(n),这样会是出队的操作效率很低。

我们可以使用一个索引front索引指向队首元素的索引,维护一个变量size来记录队列的大小,那么队尾元素的索引可以通过计算得到rear = front + size;

  • 入队操作,只需要将值赋值给rear索引处
  • 出队操作,只需要将front+1即可。
  • 此时我们就可以发现入队,出队操作都可以在O(1)内完成
//
// Created by Administrator on 2024/1/10.
//
#include "iostream"
#include "vector"

using namespace std;

class myqueue2 {
private:
    int front = 0;
    int rear = 0;
    int *nums;
    int quesize = 0;
    int queCapacity;
public:
    myqueue2(int capacity) {
        // 初始化数组
        nums = new int[capacity];
        queCapacity = capacity;
        front = quesize = 0;
    };
    //获取队列容量
    int capacity(){
        return queCapacity;
    }
    //获取队列长度
    int size(){
        return quesize;
    }
    //判断队列是否为空
    bool empty(){
        return quesize == 0;
    }
    //入队
    void push(int num) {
        if (quesize == queCapacity) {
            cout << "队列已满" << endl;
            return;
        }
        //取余操作是为了索引超出容量时,回到数组的头部
        rear = (front + quesize) % queCapacity;//计算尾指针的位置
        nums[rear] = num;
        quesize++;
    }
    //获取队首元素
    int peek(){
        if(empty()){
            throw out_of_range("队列为空");
        }
        return nums[front];
    }
    //出队
    int pop(){
        int temp = peek();
        front = (front + 1) % queCapacity;
        quesize--;
        return temp;
    }
    /* 将数组转化为 Vector 并返回 */
    vector<int> toVector() {
        // 仅转换有效长度范围内的列表元素
        vector<int> arr(quesize);
        for (int i = 0, j = front; i < quesize; i++, j++) {
            arr[i] = nums[j % queCapacity];
        }
        return arr;
    }
};
int main(){
    cout<<"测试基于数组实现的队列"<<endl;
    cout<<"将元素1,2,3添加到队列中"<<endl;
    myqueue2 myque(10);
    myque.push(1);
    myque.push(2);
    myque.push(3);
    cout<<"此时队列中的元素"<<endl;
    vector<int> temp  = myque.toVector();
    for(int i : temp){
        cout<<i<<" ";
    }
    cout<<endl;
    cout<<"获取队首元素:"<<myque.peek()<<endl;
    cout<<"队列容量:"<<myque.capacity()<<endl;
    cout<<"队列长度:"<<myque.size()<<endl;
    cout<<"队列是否为空?:"<<myque.empty()<<endl;
    cout<<"执行出队操作:"<<endl;
    myque.pop();
    cout<<"获取队首元素:"<<myque.peek()<<endl;
    cout<<"队列容量:"<<myque.capacity()<<endl;
    cout<<"队列长度:"<<myque.size()<<endl;
    cout<<"此时队列中的元素"<<endl;
    vector<int> temp1  = myque.toVector();
    for(int i : temp1){
        cout<<i<<" ";
    }
    cout<<endl;
    return 0;
}
//数据结果
测试基于数组实现的队列
将元素1,2,3添加到队列中
此时队列中的元素
1 2 3
获取队首元素:1
队列容量:10
队列长度:3
队列是否为空?:0
执行出队操作:
获取队首元素:2
队列容量:10
队列长度:2
此时队列中的元素
2 3

关注微信公众号:IT零壹学府,每日分享自己下学习经验

  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

零壹寻

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

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

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

打赏作者

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

抵扣说明:

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

余额充值