数据结构----队列

本文介绍了数据结构中的队列,强调了其先进先出(FIFO)的特性。首先讲解了顺序队列,包括C语言实现的顺序队列的基本操作如入队、出队、初始化和销毁。接着讨论了链式队列,指出其利用线性链表实现,虽然动态操作效率稍低,但能动态扩展并避免溢出问题,适合于队列操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、顺序队列


队列是一种特殊的线性表,特殊之处在于它只允许在表的前端进行删除操作,而在表的后端进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。

队列的数据元素又称为队列元素。在队列中插入一个队列元素称为入队,从队列中删除一个队列元素称为出队。因为队列只允许在一端插入,在另一端删除,所以只有最早进入队列的元素才能最先从队列中删除,故队列又称为先进先出线性表。

队列的特性是先进先出。

C语言实现:
1、队列的存储结构以及一些需要实现的方法

typedef char  ElemType;
 
#define SIZE 10
#define TRUE 1
#define FALSE 0
 
 
typedef struct queue
{
    ElemType *data;
    int head;
    int tail;
 
}queue, *pQueue;
 
void InitQueue(pQueue que);      //队列的初始化
 
int PushQue(pQueue que, ElemType val);    //入队列
 
int PopQue(pQueue que, ElemType *res);    //出队列
 
void DestroyQue(pQueue que);       //销毁队列


2、队列的判空判满以及初始化

{
    assert(que != NULL);
 
    if ((que->tail + 1) % SIZE == que->head)
    {
        return TRUE;
    }
 
    return FALSE;
}
    
static int IsEmpty(pQueue que)        //判空
{
    assert(que != NULL);
 
    if (que->head == que->tail)
    {
        return TRUE;
    }
 
    return FALSE;
}
 
 
void InitQueue(pQueue que)         //初始化
{
    assert(que != NULL);
 
    que->data = (ElemType*)malloc(sizeof(ElemType)* SIZE);
    assert(que->data != NULL);
 
    que->head = que->tail = 0;
}static int IsFull(pQueue que)    //判满



3、入队列(push)

int PushQue(pQueue que, ElemType val)
{
    assert(que != NULL);
 
    if (IsFull(que))
    {
        return FALSE;
    }
 
    que->data[que->tail++] = val;
    que->tail %= SIZE;
 
    return TRUE;
}


4、出队列(pop)

int PopQue(pQueue que, ElemType *res)
{
    assert(que != NULL && que->data != NULL);
 
    if (IsEmpty(que))
    {
        return FALSE;
    }
 
    *res = que->data[que->head++];
    que->head %= SIZE;
 
    return TRUE;
}


5、销毁队列

void DestroyQue(pQueue que)
{
    assert(que != NULL);
 
    free(que->data);
    que->data = NULL;
    que->head = que->tail = 0;
}


 

C++实现:

 

typedef int  ElemType;
#define SIZE 10
 
class Queue
{
private:
    ElemType *_data;
    int _head;
    int _tail;
    bool IsFull();    //判满
    bool IsEmpty();    //判空
public:
    Queue();
    Queue(const Queue &src);    //拷贝构造函数
    Queue& operator= (const Queue& src);    //等号运算符的重载
    ~Queue();
    bool Push(ElemType val);    //入队列
    bool Pop();    //出队列
    ElemType GetQue();    //去队列头的元素
    void show();    //打印整个队列
};
bool Queue::IsFull()
{
    assert(this != NULL);
 
    if ((_tail + 1) % SIZE == _head)
    {
        return true;
    }
 
    return false;
}
bool Queue::IsEmpty()
{
    assert(this != NULL);
 
    if (_head == _tail)
    {
        return true;
    }
 
    return false;
}
Queue::Queue()
{
    assert(this != NULL);
 
    _data = new ElemType[SIZE];
    assert(_data != NULL);
    _head = 0;
    _tail = 0;
}
Queue::Queue(const Queue &src)
{
    _data = new ElemType[sizeof(src._data)];
    for (int i = src._head; i < src._tail; ++i)
    {
        _data[src._head] = src._data[i];
    }
    _head = src._head;
    _tail = src._tail;
}
Queue& Queue::operator= (const Queue& src)
{
    if (this == &src)
    {
        return *this;
    }
    if (_data != NULL)
    {
        delete[]_data;
    }
    _data = new ElemType[sizeof(src._data)];
    for (int i = src._head; i < src._tail; ++i)
    {
        _data[src._head] = src._data[i];
    }
    _head = src._head;
    _tail = src._tail;
 
    return *this;
}
Queue::~Queue()
{
    if (NULL != _data)
    {
        delete[]_data;
        _data = NULL;
        _head = 0;
        _tail = 0;
    }
}
bool Queue::Push(ElemType val)
{
    assert(this != NULL);
 
    if (IsFull())
    {
        return false;
    }
 
    _data[_tail++] = val;
    _tail %= SIZE;
 
    return true;
}
bool Queue::Pop()
{
    assert(this != NULL && _data != NULL);
 
    if (IsEmpty())
    {
        return false;
    }
 
    _head++;
    _head %= SIZE;
 
    return true;
}
ElemType Queue::GetQue()
{
    assert(this != NULL);
 
    if (IsEmpty())
    {
        return 0;
    }
 
    return _data[_head];
}
 
void Queue::show()
{
    assert(this != NULL);
 
    for (int i = _head; i < _tail; i++)
    {
        cout << _data[i] << " ";
    }
    cout << endl;
}


二、链式队列

在队列的形成过程中,可以利用线性链表的原理,来生成一个队列。

利用链表的队列,要动态创建和删除节点,效率较低,但是可以动态增长。

队列采用的FIFO(first in first out),新元素(等待进入队列的元素)总是被插入到链表的尾部,而读取的时候总是从链表的头部开始读取。每次读取一个元素,释放一个元素。所谓的动态创建,动态释放。因而也不存在溢出等问题。由于链表由结构体间接而成,遍历也方便。

链式队列的实现:

template<typename T>
class Mqueue
    Mqueue()
{
public:
    {
        _head = NULL;
        _tail = NULL;
    }
    ~Mqueue()
    {
        if (_head == NULL)
        {
            return;
        }
 
        while (_head != _tail)
        {
            pop();
        }
        delete _head;
        _head = _tail = NULL;
    }
    void push(T val)
    {
        Node *p = new Node;
        p->_val = val;
        p->_next = NULL;
        if (_head == NULL && _tail == NULL)
        {
            _head = p;
            _tail = p;
        }
        else
        {
            _tail->_next = p;
            _tail = p;
        }
    }
    int pop()
    {
        if (_head == NULL)
        {
            return -1;
        }
        Node *p = _head;
        _head = p->_next;
        p->_next = NULL;
        delete p;
 
    }
    T top()
    {
        return _tail->_val;
    }
 
    void show()
    {
        Node *p = _head;
        while (p != NULL)
        {
            cout << p->_val << "   ";
            p = p->_next;
        }
        cout << endl;
    }
private:
    class Node
    {
    private:
        T _val;
        Node *_next;
 
        friend class Mqueue;
 
    public:
        Node()
        {
            _next = NULL;
        }
    };
 
    Node *_head;
    Node *_tail;
 


 


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值