C/C++数据结构之用链表实现队列

概述

在前一篇文章中,我们已经用数组实现了队列。在本篇文章中,我们将使用链表来实现队列。使用链表的优点是:动态增长,扩容时更加平滑。缺点是:略微复杂,需要额外管理所有节点。队列相关的操作,仍然是下面6个接口。

Enqueue:向队尾添加一个元素。

Dequeue:从队首移除顶部元素,并返回该元素。

Front:查看队首元素,但不移除它。

Rear:查看队尾元素,但不移除它。

IsEmpty:检查队列是否为空。

Size:获取队列中元素的数量。

实现原理

我们使用一个带头指针和尾指针的单链表来实现队列。其中,头指针对应链表的头部,尾指针对应链表的尾部。入队操作在尾部插入新节点,出队操作从头部删除节点。所有操作均维护头指针和尾指针的正确性,确保队列行为符合FIFO规则。

在下面队列CLinkedListQueue的实现中,我们声明了两个成员变量m_pFront和m_pRear。m_pFront代表队首,m_pRear代表队尾。

cpp 复制代码
class CLinkedListQueue
{
public:
    CLinkedListQueue();
    ~CLinkedListQueue();

    void Enqueue(int nValue);
    int Dequeue();
    int Front();
    int Rear();
    bool IsEmpty();
    int Size();

private:
    struct Node
    {
        int nData;
        Node* pNext;
    };

    Node* m_pFront;
    Node* m_pRear;
};

Enqueue操作

入队就是在链表的尾部插入一个新节点,详细步骤如下。

1、创建一个新节点。

2、如果队列为空,将m_pFront和m_pRear都指向新节点。

3、如果队列非空,将当前尾节点m_pRear的pNext指向新节点pNode,并更新尾指针为pNode。

具体如何实现,可参考下面的示例代码。

cpp 复制代码
void CLinkedListQueue::Enqueue(int nValue)
{
    Node* pNode = new Node();
    pNode->nData = nValue;
    pNode->pNext = NULL;

    if (IsEmpty())
    {
        m_pFront = m_pRear = pNode;
    }
    else
    {
        m_pRear->pNext = pNode;
        m_pRear = pNode;
    }
}

Dequeue操作

出对就是删除链表头部节点,并返回其值,详细步骤如下。

1、如果队列为空,抛出异常。

2、取出队首节点的值,保存为临时变量。

3、将队首指针更新为下移一位后的指针,如果新的队首指针为空,则将队尾指针也设置为空。

4、释放旧节点的内存。

5、返回上面的临时变量。

具体如何实现,可参考下面的示例代码。

cpp 复制代码
int CLinkedListQueue::Dequeue()
{
    if (IsEmpty())
    {
        throw underflow_error("queue is empty");
    }

    Node* pTemp = m_pFront;
    int nValue = pTemp->nData;

    m_pFront = m_pFront->pNext;
    if (m_pFront == NULL)
    {
        m_pRear = NULL;
    }

    delete pTemp;
    return nValue;
}

完整实现

Front操作、Rear操作、IsEmpty操作、Size操作都比较简单,这里就不再赘述了。CLinkedListQueue类的完整实现,可参考下面的示例代码。

cpp 复制代码
#include <iostream>
#include <stdexcept>

using namespace std;

class CLinkedListQueue
{
public:
    CLinkedListQueue();
    ~CLinkedListQueue();

    void Enqueue(int nValue);
    int Dequeue();
    int Front();
    int Rear();
    bool IsEmpty();
    int Size();

private:
    struct Node
    {
        int nData;
        Node* pNext;
    };

    Node* m_pFront;
    Node* m_pRear;
};

CLinkedListQueue::CLinkedListQueue() : m_pFront(NULL), m_pRear(NULL)
{
    NULL;
}

CLinkedListQueue::~CLinkedListQueue()
{
    while (!IsEmpty())
    {
        Dequeue();
    }
}

void CLinkedListQueue::Enqueue(int nValue)
{
    Node* pNode = new Node();
    pNode->nData = nValue;
    pNode->pNext = NULL;

    if (IsEmpty())
    {
        m_pFront = m_pRear = pNode;
    }
    else
    {
        m_pRear->pNext = pNode;
        m_pRear = pNode;
    }
}

int CLinkedListQueue::Dequeue()
{
    if (IsEmpty())
    {
        throw underflow_error("queue is empty");
    }

    Node* pTemp = m_pFront;
    int nValue = pTemp->nData;

    m_pFront = m_pFront->pNext;
    if (m_pFront == NULL)
    {
        m_pRear = NULL;
    }

    delete pTemp;
    return nValue;
}

int CLinkedListQueue::Front()
{
    if (IsEmpty())
    {
        throw underflow_error("queue is empty");
    }

    return m_pFront->nData;
}

int CLinkedListQueue::Rear()
{
    if (IsEmpty())
    {
        throw underflow_error("queue is empty");
    }

    return m_pRear->nData;
}

bool CLinkedListQueue::IsEmpty()
{
    return m_pFront == NULL;
}

int CLinkedListQueue::Size()
{
    int nSize = 0;
    Node* pTemp = m_pFront;
    while (pTemp != NULL)
    {
        ++nSize;
        pTemp = pTemp->pNext;
    }

    return nSize;
}

int main()
{
    CLinkedListQueue q;

    q.Enqueue(66);
    q.Enqueue(77);
    q.Enqueue(88);

    cout << "Front element: " << q.Front() << endl;
    cout << "Rear element: " << q.Rear() << endl;
    cout << "Dequeue: " << q.Dequeue() << endl;
    cout << "Dequeue: " << q.Dequeue() << endl;
    cout << "Current size: " << q.Size() << endl;
    cout << "Is empty: " << (q.IsEmpty() ? "True" : "False") << endl;
    return 0;
}
相关推荐
载数而行5201 天前
QT的五类布局
c++·qt·学习
故事和你911 天前
sdut-程序设计基础Ⅰ-实验五一维数组(8-13)
开发语言·数据结构·c++·算法·蓝桥杯·图论·类和对象
载数而行5201 天前
QT的QString类
c++·qt·学习
芯联智造1 天前
【stm32简单外设篇】- WS2812单线地址式 RGB 灯带
c语言·stm32·单片机·嵌入式硬件
bu_shuo1 天前
Visual C++2010学习版(全国计算机等级二级考试版)安装记录
c++·cpp·visual c++·计算机二级
Titan20241 天前
Linux环境变量个人笔记
linux·服务器·c++
djarmy1 天前
ubuntu20.04搭建openharmony6.0的master分支。构建编译环境报错解决记录
c语言·ubuntu
记忆多1 天前
c++名字空间 函数模版 左右值
开发语言·c++·算法
2401_889884661 天前
高性能计算通信库
开发语言·c++·算法
郝YH是人间理想1 天前
Pandas库DataFrame数据结构
数据结构·pandas