数据结构——队列的实现

本文详细介绍了顺序队列(基于数组)和链式队列的实现,包括enqueue(入队)、dequeue(出队)、isEmpty和peek操作,以及链队的节点类和特殊处理如哨兵节点的使用。
摘要由CSDN通过智能技术生成

顺序队列(循环队列):

在实现顺序队列时我依然采用了数组作为基础的数据结构,与栈不同的是,队列是先进先出,而栈是后进先出,我们使用top和rear两个整数分别指向队列的头部和尾部,在队列为空时top=rear;由于队列先进先出的特性我们可以将顺序队列设计为一个循环队列。

代码实现了队列的enqueue(入队),dequeue(出队),isempty(检查队列是否为空),peek(返回队列头部元素)这几个操作。

以下是代码部分:

#include<iostream>
using namespace std;

// sqqueue 类定义了一个循环队列
class sqqueue {
private:
    int front;  // 指向队列的前端
    int rear;   // 指向队列的后端
    int* queue; // 动态数组,用于存储队列元素
    int maxsize_; // 队列的最大容量

public:
    // 构造函数
    sqqueue(int maxsize) :maxsize_(maxsize + 1), front(0), rear(0) {
        queue = new int[maxsize_]; // 分配内存
    }

    // 析构函数
    ~sqqueue() {
        delete[] queue; // 释放内存
    }

    // 入队函数
    bool enqueue(int data) {
        // 检查队列是否已满
        if ((rear + 1) % maxsize_ == front) {
            cout << "This queue is full" << endl;
            return false;
        }
        // 添加元素到队列并更新 rear 指针
        queue[rear] = data;
        rear = (rear + 1) % maxsize_;
        return true;
    }

    // 出队函数
    bool dequeue() {
        // 检查队列是否为空
        if (front == rear) {
            cout << "This queue is empty" << endl;
            return false;
        }
        // 移除元素并更新 front 指针
        front = (front + 1) % maxsize_;
        return true;
    }

    // 检查队列是否为空
    bool isempty() {
        return front == rear;
    }

    // 获取队列的前端元素
    int peek() {
        try {
            // 检查队列是否为空
            if (front == rear) {
                throw "This queue is empty";
            }
            return queue[front];
        }
        catch (const char* e) {
            // 捕获并处理异常
            cerr << "Error:" << e << endl;
            return 0; // 返回默认值
        }
    }
};

队列的链式结构:

我们先看链队的节点类:

class qnode {
public:
	int data_;
	qnode* next;
	qnode(int data):data_(data),next(nullptr){}
};

 我们设置了front,rear指针作为链队的私有属性,front指针指向队列的头结点。rear指针指向队列的最后一个元素,在初始化时两者都指向头结点。

以下是代码实现:

#include<iostream>
using namespace std;

// qnode 类定义了队列的节点
class qnode {
public:
    int data_;      // 节点存储的数据
    qnode* next;    // 指向下一个节点的指针

    // 构造函数
    qnode(int data): data_(data), next(nullptr) {}
};

// linkqueue 类定义了一个链式队列
class linkqueue {
private:
    qnode* front;  // 指向队列前端的指针
    qnode* rear;   // 指向队列后端的指针

public:
    // 构造函数
    linkqueue() {
        qnode* temp = new qnode(0); // 创建一个哨兵节点
        front = temp; // 初始化 front 和 rear 指向哨兵节点
        rear = temp;
    }

    // 入队函数
    bool enqueue(int data) {
        qnode* temp = new qnode(data); // 创建一个新节点
        // 当队列为空时,将新节点添加为第一个元素
        if (front->next == nullptr) {
            front->next = temp;
            rear = temp;
            return true;
        }
        // 正常情况下,将新节点添加到队列末尾
        rear->next = temp;
        rear = temp; // 更新 rear 指针
        return true;
    }

    // 出队函数
    bool dequeue() {
        // 检查队列是否为空
        if (front->next == nullptr) {
            cout << "This queue is empty" << endl;
            return false;
        }
        // 移除队列的第一个元素
        qnode* todelete = front->next;
        front->next = front->next->next;
        delete todelete; // 释放被删除节点的内存
        // 特殊情况处理:如果队列变空,则 rear 也应指向哨兵节点
        if (front->next == nullptr) {
            rear = front;
        }
        return true;
    }

    // 计算队列长度
    int length() {
        int len = 0;
        qnode* current = front->next;
        // 遍历队列以计算长度
        while (current != nullptr) {
            len++;
            current = current->next;
        }
        return len;
    }

    // 查看队列的前端元素
    int peek() {
        try {
            // 检查队列是否为空
            if (front->next == nullptr) {
                throw "This queue is empty";
            }
            return front->next->data_; // 返回队列的第一个元素
        }
        catch (const char* e) {
            // 捕获并处理异常
            cerr << "Error:" << e << endl;
            return 0; // 返回默认值
        }
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值