一点 · 队列

本文介绍了队列数据结构的基本概念及其实现方式,包括队列的抽象数据类型定义,顺序队列与链式队列的具体实现,并探讨了循环顺序表在队列实现中的应用。

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

队列

队列queue也是一种线性表,但它被限制为只能在队尾插入,称为入队操作(enqueue),从队首删除,称为出队操作(dequeue),因此也被称为FIFO线性表,即先进先出。

队列的ADT

template <typename E> class Queue {
private:
  void operator =(const Queue&) {}     // Protect assignment
  Queue(const Queue&) {}         // Protect copy constructor

public:
  Queue() {}          // Default
  virtual ~Queue() {} // Base destructor

  // Reinitialize the queue.  The user is responsible for
  // reclaiming the storage used by the queue elements.
  virtual void clear() = 0;

  // Place an element at the rear of the queue.
  // it: The element being enqueued.
  virtual void enqueue(const E&) = 0;

  // Remove and return element at the front of the queue.
  // Return: The element at the front of the queue.
  virtual E dequeue() = 0;

  // Return: A copy of the front element.
  virtual const E& frontValue() const = 0;

  // Return: The number of elements in the queue.
  virtual int length() const = 0;
};

如果使用普通的顺序表来实现队列,就会导致enqueue和dequeue操作中,一个时间代价为Θ(n),另一个为Θ(1),分别对应队首队尾正放与倒放的情况。

因此采用一种循环顺序表的方式来实现,即顺序表的最后一个结点的next指针指向head,且每次enqueue操作使得front后移,dequeue操作使得rear也后移。

这带来一个小问题,就是对于一个有着n长度的顺序表来说,它应该能表示n+1种状态,但是由于front和rear各指向一个位置,导致实际上只能表示n种状态,这就是的第一种状态,空状态,和第n+1种状态,满状态的区分上产生了困难,一种解决方法是单独设置一个布尔成员变量,用来记录是否为空,或者将顺序表长度设为n+1,只在其中保存最多n个元素,便可表示,n+1种状态。

链式队列
一种简单修改后的链表,只是固定front和rear指针指向链表的的头和尾,但是只能在front处删除,在rear处添加,而初始化时,将front和rear均指向头结点。
链式队列的实现:
template <typename E> class LQueue: public Queue<E> {
private:
  Link<E>* front;       // Pointer to front queue node
  Link<E>* rear;        // Pointer to rear queue node
  int size;                // Number of elements in queue

public:
  LQueue(int sz =defaultSize) // Constructor 
    { front = rear = new Link<E>(); size = 0; }

  ~LQueue() { clear(); delete front; }      // Destructor

  void clear() {           // Clear queue
    while(front->next != NULL) { // Delete each link node
      rear = front;
      delete rear;
    }
    rear = front;
    size = 0;
  }

  void enqueue(const E& it) { // Put element on rear
    rear->next = new Link<E>(it, NULL);
    rear = rear->next;
    size++;
  }

  E dequeue() {              // Remove element from front
    Assert(size != 0, "Queue is empty");
    E it = front->next->element;  // Store dequeued value
    Link<E>* ltemp = front->next; // Hold dequeued link
    front->next = ltemp->next;       // Advance front
    if (rear == ltemp) rear = front; // Dequeue last element
    delete ltemp;                    // Delete link
    size --;
    return it;                       // Return element value
  }

  const E& frontValue() const { // Get front element
    Assert(size != 0, "Queue is empty");
    return front->next->element;
  }

  virtual int length() const { return size; }
};


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值