模拟实现 队列

先介绍一下队列:
队列(queue)在计算机科学中,是一种先进先出的线性表。
它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作。进行插入操作的端称为队尾,进行删除操作的端称为队头。队列中没有元素时,称为空队列。 由于队列在队头进行删除,队尾进行插入,所以用链表进行实现就比较方便。
队列采用的FIFO(first in first out),新元素(等待进入队列的元素)总是被插入到链表的尾部,而读取的时候总是从链表的头部开始读取。每次读取一个元素,释放一个元素。所谓的动态创建,动态释放。因而也不存在溢出等问题。由于链表由结构体间接而成,遍历也方便。
用下图来表示队列的实现方式:
这里写图片描述

   队列的基本运算:
   push(data)//插入
   pop()//删除
   front()//返回队头元素
   rear()//返回队尾元素
   size()//返回队列中元素的个数

下面用代码进行实现:

#include<iostream>
#include<assert.h>
using namespace std;

template <typename T>
struct QueueNode
{
    T _a;//数据
    QueueNode *next;//指向下一个节点

    QueueNode(const T& X = T())
        :_a(X)
        ,next(NULL)
    {}
};
template <typename T>
class Queue
{

public:
    typedef struct QueueNode<T> Node;//类型重定义

    Queue()//构造函数
        :_rear(NULL)
        ,_front(NULL)
    {}

    Queue(const Queue<T>& Q)//拷贝构造函数
        :_rear(NULL)
        ,_front(NULL)
    {
        if(Q._front)
        {
            Node* p1 = Q._front;
            _front = _BuyNode(Q._front->_a);
            _rear = _front;
            while(p1)
            {
                Node* NewNode = _BuyNode(p1->_a);
                _rear->next = NewNode;
                p1 = p1->next;
            }
        }
    }
    ~Queue()//析构函数
    {
        Node* p = _front;
        while(p)//这里需要将节点一个一个释放
        {
            Node* p1 = p->next;
            delete p;
            p = p1;
        }
        _front = NULL;
        _rear = NULL;
    }
    void Pop()//删除
    {
        if(_front == _rear)
        {
            delete _front;
            _front = _rear = NULL;
        }
        else
        {
            Node* p = _front;
            _front = p->next;
            delete p;
        }
    }

    void Push(const T& data)//插入
    {
        Node* node = _BuyNode(data);
        if(_front == NULL)
        {
            _front = _rear = node;
        }
        else
        {
            _rear->next = node;
            _rear = node;
        }
    }
    int Size()//返回队列中元素的个数
    {
        int count = 0;
        Node* p = _front;
        while(p)
        {
            count++;
            p = p->next;
        }
        return count;
    }

    T& Front()//返回队头元素
    {
        assert(Size());
        return _front->_a;
    }
    T& Rear()//返回队尾元素
    {
        assert(Size());
        return _rear->_a;

    }
    bool Empty()//判断队列是否为空
    {
        return !(_front);
    }
protected:
    Node* _BuyNode(T data)//创建新的节点
    {
        Node* tmp = new Node;
        tmp->_a = data;
        tmp->next = NULL;
        return tmp;
    }

    Node* _rear;//队尾
    Node* _front;//队头
};
int main()
{
    //构建一个队列的对象Q
    Queue<int> Q;
    //插入6个元素
    Q.Push(1);
    Q.Push(2);
    Q.Push(3);
    Q.Push(4);
    Q.Push(5);
    Q.Push(6);
    //删除两个元素
    Q.Pop();
    Q.Pop();
    Q.Front();//返回队头元素
    Q.Rear();//返回队尾元素
    Q.Size();//返回队列元素的个数
    Q.Empty();//判断是否为空队列
    while(Q.Size())//输出队列中的元素
    {
        cout<<Q.Front()<<" ";
        Q.Pop();//由于只可访问队头元素,所以每次将队头元素删除才可访问下一元素
    }
    cout<<endl;
    return 0;
}

结果:
这里写图片描述

以上代码的不足之处:由于输出元素时将队头元素删除,所以输出完后队列就成空队列了。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值