数据结构之队列

队列

一、队列的概念

队列是仅限在表尾进行插入,表头进行删除的线性表,它遵循先进先出(First-In-FIrst-Out,FIFO)的原则。队列就像排队等候的人群一样,最先进入队列的元素将优先被处理或移除。

在计算机科学中,队列通常用于实现 排队系统、任务调度、消息传递(消息队列可用于进程间通信)。我们一般可以用 顺序表 或 链表 来实现队列。

二、入队

1、入队的概念

队列的插入操作叫做入队,它是将数据元素从队尾进行插入的过程。

2、入队的步骤

第1步:将元素添加到队列尾部,更新队尾指针(适用于链表)或者索引(适用于顺序表)。

第2步:队列的大小增加1.

3、入队的顺序表实现

template<typename T>
void Queue<T>::enqueue(T element){
    if(rear == capacity){
        resize();
    }
    data[rear++] = element;
}

4、入队的链表实现

template<typename T>
void Queue<T>::enqueue(T element){
    if(rear == NULL){
        rear = new Node(element);
        front = rear;
    }else{
        rear->next = new Node(element);
        rear = rear->next;
    }
    ++size;
}

三、出队

1、出队的概念

队列的删除操作叫做出队,它是将队首元素进行删除的过程。

2、出队的步骤

第1步:删除队首元素,更新队首指针(适用于链表)或者索引(适用于顺序表)。

第2步:队列的大小减小1

3、出队的顺序表实现

template<typename T>
T Queue<T>::dequeue(){
    if(front == rear){
        throw std::underflow_error("Queue is empty");
    }
    return data[front++];       //front指针右移一位
}

4、出队的链表实现

template<typename T>
T Queue<T>::dequeue(){
    if(front == NULL){
        throw std::underflow_error("Queue is empty");
    }
    T element = front->data;
    Node *temp = front;
    front = front->next;
    delete temp;
    --size;
    if(size == 0) rear = NULL;
    return element;
}

四、获取队首元素

1、获取队首元素的概念

返回队首指针(或者索引)指向的元素的值,无论是链表还是顺序表,都可以通过队首指针(或者索引)在O(1)的时间复杂度获取到队首元素。

2、获取队首元素的步骤

利用队首指针(或者索引)获取队首元素并返回,由于是查询操作,所以不会改变队列本身的数据。

3、获取队首元素的顺序表实现

template<typename T>
T Queue<T>::getFront() const{
    if(front == rear){
        throw std::underflow_error("Queue is empty");
    }
    return data[front];
}

4、获取队首元素的链表实现

template<typename T>
T Queue<T>::getFront() const {
    if(front == NULL){
        throw std::underflow_error("Queue is empty");
    }
    return front->data;
}

五、队列的顺序表实现

#include<iostream>
#include<stdexcept>
​
using namespace std;
​
template<typename T>
class Queue{
​
private:
    T *data;
    int front;      //指向队首元素
    int rear;       //指向队尾元素的下一个位置
    int capacity;
    void resize();
​
public:
    Queue() : data(new T[capacity]), front(0), rear(0), capacity(10) {}     //data(new T[capacity])根据编译器的不同这里capacity未被赋值可能会报错可换成date(new T[10])
    ~Queue();
    void enqueue(T element);        //入队
    T dequeue();        //出队
    T getFront() const;
    int getSize() const;
};
​
template<typename T>
void Queue<T>::resize(){
    T *newData = new T[capacity * 2];
    for(int i = 0; i < rear; i++){
        newData[i] = data[i];
    }
    delete[] data;
    data = newData;
    capacity *= 2;
}
​
template<typename T>
Queue<T>::~Queue(){
    delete[] data;
}
​
template<typename T>
void Queue<T>::enqueue(T element){
    if(rear == capacity){
        resize();
    }
    data[rear++] = element;
}
​
template<typename T>
T Queue<T>::dequeue(){
    if(front == rear){
        throw std::underflow_error("Queue is empty");
    }
    return data[front++];       //front指针右移一位
}
​
template<typename T>
T Queue<T>::getFront() const{
    if(front == rear){
        throw std::underflow_error("Queue is empty");
    }
    return data[front];
}
​
template<typename T>
int Queue<T>::getSize() const{
    return rear - front;
}
​
​
​
​
int main(){
    Queue<int> q;
    q.enqueue(3);
    q.enqueue(4);
    cout << q.getFront() << endl;       //3
    q.enqueue(5);
    cout << q.getFront() << endl;       //3
    q.dequeue();
    cout << q.getFront() << endl;       //4
    cout << q.getSize() << endl;        //2
    return 0;
}

六、队列的链表实现

#include<iostream>
#include<stdexcept>
​
using namespace std;
​
template<typename T>
class Queue{
private:
    struct Node{
        T data;
        Node *next;
        Node (T d) : data(d), next(NULL) {}
    };
    Node *front;
    Node *rear;
    int size;
​
public:
    Queue() : front(NULL), rear(NULL), size(0) {}
    ~Queue();
    void enqueue(T element);
    T dequeue();
    T getFront() const;
    int getSize() const;
};
​
template<typename T>
Queue<T>::~Queue(){
    while(front){
        Node *temp = front;
        front = front->next;
        delete temp;
    }
}
​
template<typename T>
void Queue<T>::enqueue(T element){
    if(rear == NULL){
        rear = new Node(element);
        front = rear;
    }else{
        rear->next = new Node(element);
        rear = rear->next;
    }
    ++size;
}
​
template<typename T>
T Queue<T>::dequeue(){
    if(front == NULL){
        throw std::underflow_error("Queue is empty");
    }
    T element = front->data;
    Node *temp = front;
    front = front->next;
    delete temp;
    --size;
    if(size == 0) rear = NULL;
    return element;
}
​
template<typename T>
T Queue<T>::getFront() const {
    if(front == NULL){
        throw std::underflow_error("Queue is empty");
    }
    return front->data;
}
​
template<typename T>
int Queue<T>::getSize() const {
    return size;
}
​
int main(){
    Queue<int> q;
    q.enqueue(3);
    q.enqueue(4);
    cout << q.getFront() << endl;       //3
    q.enqueue(5);
    q.dequeue();
    cout << q.getFront() << endl;       //4
    cout << q.getSize() << endl;        //2
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值