队列知识整理

本文介绍了队列的基本概念,特别是循环队列和链式队列的实现,以及它们在数据结构中的应用,包括队列的性质、操作方法和STL中现成队列类的使用。
摘要由CSDN通过智能技术生成

说在前面:本人只是一位普通的菜菜,文章更多是整理之前的知识,有错误欢迎大家指正。

队列的性质

队列跟堆栈的区别是数据弹出的顺序不同,队列是先进先出,后进后出,类似于排队办理业务,新客户(新数据)接在队伍的尾部,办理完业务的客户(老数据)从队伍前面离开。

基于队列的性质,队列可以解决银行排队模拟等问题。

循环队列

1.用数组储存数据

优点:简单易理解(不要用到指针,大家可能更喜欢)

缺点:由于数组的大小一开始就确定,所以队列的最大大小确定了无法改变,不灵活。

2.一般循环队列的定义

const int MAX_SIZE = 100;
class CirQueue
{
private:
    char* data;        //指向队列存储空间
    int front;                    //队首下标
    int rear;                     //队尾下标
    int mSize;
    int sum;         // 存放队列的数组的大小
public:
    CirQueue();                   //建立缺省长度的队列
    CirQueue(int s);              //建立长度为size的队列
    ~CirQueue();                  //清空队列,释放内存
    bool enQueue(char item);  //入队
    bool deQueue();      //出队
    char getFront();     //读取队头元素,但不删除
    bool isEmpty();               //判断队列是否为空
    bool isFull();                //判断队列是否为满
    void clearQueue();            //清空队列
    void displayQueue();          //显示队列内容
    int queueLength();            //获取队列元素个数
};

3.函数的实现

 构造函数 :成员变量设初值,注意front和rear初值设为0不是-1,要保证front和rear的值在数组下标范围之内。

 这里提一嘴,因为要实现循环的效果,所以front和rear超过最大值后,要归零,那么这么实现这个效果呢。

有一个神奇的公式 front=(front+1)/msize,这里的msize是数组的大小,通过这个公式,我们就可以实现下标循环的效果。

还有一件事,front指向的是有数据前的位置,也就是说front这个位置没数据,front后一个位置才有数据,rear就不一样,它指向的位置就是最后一个数据。(这些其实是习惯问题,可能每个人的定义都不一样,但自己一定要清楚,自己数据的含义)

下面是函数的具体实现

CirQueue::CirQueue()
{
    mSize = MAX_SIZE;
    data = new char[mSize];
    front = 0;
    rear = 0;
    sum = 0;
}
CirQueue::CirQueue(int s)
{
    mSize = s;
    data = new char[mSize];
    front = 0;
    rear = 0;
    sum = 0;
}
CirQueue::~CirQueue()
{
    delete[] data;
}
bool CirQueue::enQueue(char item)
{
    if (isFull())
    {
        return false;
    }
    rear = (rear + 1) % mSize;
    data[rear] = item;
    sum++;
    return true;
}
bool CirQueue::deQueue()
{
    if (isEmpty())
    {
        return false;
    }
    front = (front + 1) % mSize;
    sum--;
    return true;
}
char CirQueue::getFront()
{
    int i;
    if (isEmpty())
    {
        return 0;
    }
    i = (front + 1) % mSize;
    return data[i];
}
bool CirQueue::isFull()
{
    if (sum == mSize)
    {
        return true;
    }
    return false;
}
bool CirQueue::isEmpty()
{
    if (sum == 0)
    {
        return true;
    }
    return false;
}
void CirQueue::clearQueue()
{
    sum = 0;
    front = rear;
}
void CirQueue::displayQueue()
{
    if (isEmpty())
    {
        cout << "队列为空";
        return;
    }
    int i;
    for (i = (front + 1) % mSize; i != rear; i = (i + 1) % mSize)
    {
        cout << data[i] << ' ';
    }
    cout << data[i] << endl;
}
int CirQueue::queueLength()
{
    return sum;
    //return (rear+mSize-front)%mSize; 也可以写这个
}

 链式队列

1.用指针将一个个数据串起来

结构体定义为一个数据域一个指针域

struct Node
{
    char data;
    struct Node* next;
};

2.各种函数的实现

class LinkQueue
{
private:
    Node* front, * rear;       //队列的头和尾
    int length;         //队列元素个数
public:
    LinkQueue();                                //建立头结点,初始化属性
    ~LinkQueue();                              //释放队列空间
    void enQueue(char x);        //入队
    bool deQueue();//出队
    char getFront();//获取队头元素
    bool isEmpty();                            //判断队列是否为空
    void clearQueue();                       //清空队列
    void displayQueue();                   //显示队列内容
    int queueLength();                      //获取队列元素个数
};
LinkQueue::LinkQueue()
{
    front = new Node;
    front->next = NULL;
    rear = front;
    length = 0;
}
LinkQueue::~LinkQueue()
{
    Node* p;
    Node* q;
    p = front;
    q = p->next;
    while (q != NULL)
    {
        delete p;
        p = q;
        q = q->next;
    }
    delete p;
}
void LinkQueue::enQueue(char x)
{
    Node* s = new Node;
    s->data = x;
    s->next = NULL;
    rear->next = s;
    rear = s;
    length++;
    return;
}
bool LinkQueue::deQueue()
{
    if (isEmpty())
    {
        return false;
    }
    Node* p;
    p = front->next;
    front->next = p->next;
    delete p;
    length--;
    if (isEmpty())
    {
        rear = front;
    }
    return true;
}
char LinkQueue::getFront()
{
    if (isEmpty())
    {
        return 0;
    }
    return front->next->data;
}
bool LinkQueue::isEmpty()
{
    if (length == 0)
    {
        return true;
    }
    return false;
}
void LinkQueue::clearQueue()
{
    Node* p;
    p = front->next;
    while (front->next != NULL)
    {
        front->next = p->next;
        delete p;
        p = front->next;
    }
    rear = front;
    length = 0;
    return;
}
void LinkQueue::displayQueue()
{
    cout << '[' << length << ']' << ' ';
    if (isEmpty())
    {
        cout << "队列为空。" << endl;
        return;
    }
    Node* p, * q;
    p = front;
    q = front->next;
    while (q != NULL)
    {
        cout << q->data << ' ';
        p = q;
        q = p->next;
    }
    cout << endl;
    return;
}
int LinkQueue::queueLength()
{
    return length;
}

其中front和rear的定义基本和循环队列相同。

其他函数也不难理解,我就不多讲解了(其实是太懒)

STL

我们平时可以使用现成的队列类

只需要加上头文件

#include<queue>

即可。

  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值