数据结构-队列

定义:队列也是一种受限的线性表。它限定所有的插入只能在表的一端进行,所有的删除只能在表的另一端进行。先进先出(FIFO)原则。队头front,队尾rear。队列的存储方式主要有顺序存储和链式存储。

队列的顺序存储结构

和顺序表一样,使用一个一维数组存放当前队列中的元素。由于队列、队头、队尾位置总是变化的,因此使用两个 Int 型变量 front 和 rear 分别指示当前队头元素和队尾元素在数组中的位置。但是要注意:front存放的是当前队头元素的位置,rear存放的是当前队尾元素的下一个位置,即下一个将要入队元素的位置

但是由上图可以看出,随着入队和出队进行,队列元素逐渐向数组末端移动,当rear移出数组时,尽管前端有空余,不能入队,产生假溢出。解决方法:采用循环队列。如下图,当元素出队,front顺时针加1,当元素出队,rear顺时针加1.

通过取余操作实现front和rear的循环移动:
rear进一:rear=(rear+1)%maxsize
front进一:front=(front+1)%maxsize
循环队列使用一个int变量count记录队列中元素个数,判断队空或者满。队空和队满时都有rear=front。

//字符型循环队列类的定义
#include <iostream>
class Queue
{
public:
      Queue(int m=10);
      ~Queue(){ delete[] elem; };
      bool IsEmpty(){ return count == 0; }
      bool IsFull(){ return count == maxsize; }
      bool EnQueue(const char &x);    
      bool DeQueue();
      bool Front(char &x);  //将队头元素取到x
      int Length(){ return count; }
      void ClearQueue();
private:
      int front, rear;
      int count;
      int maxsize;
      char* elem;
};

Queue::Queue(int m)
{
      elem = new char[m];
      maxsize = m;
      front = 0;
      rear = 0;
      count = 0;
}

bool Queue::EnQueue(const char &x)
{
      if (IsFull()) return false;
      elem[rear] = x;
      rear = (rear + 1) % maxsize;
      count++;
      return true;
}

bool Queue::DeQueue()
{
      if (IsEmpty()) return false;
      front=(front+1)%maxsize;
      count--;
      return true;
}

bool Queue::Front(char &x)
{
      if (IsEmpty())return false;
      x = elem[front];
      //front = (front + 1) % maxsize;
      //count--;
      return true;
}

void Queue::ClearQueue()
{
      front = rear = 0;
      count = 0;
}

队列的链式存储结构

用只允许子啊表头删除和表尾插入的单链表实现。设置两个指针,指向头节点的front和指向尾节点的rear。

依旧使用count记录队列中元素个数。

//链式存储结构的队列类定义
class LinkedQueue;
class Node
{
      friend class LinkedQueue;
private:
      char data;
      Node* next;
};
class LinkedQueue
{
public:
      LinkedQueue();
      ~LinkedQueue();
      bool IsEmpty(){ return count == 0; }
      void EnQueue(const char &x); //入队,由于肯定不会出现full情况,所以不用返回true/false
      bool DeQueue();      //出队
      bool Front(char &x);  //取队头元素到x,但是不出队
      void ClearLinkedQueue();
private:
      int count;
      Node *front, *rear;
};

LinkedQueue::LinkedQueue()
{
      front = rear = 0;
      count = 0;
}

LinkedQueue::~LinkedQueue()
{
      ClearLinkedQueue();
}

void LinkedQueue::EnQueue(const char &x)
{
      Node *p = new Node;
      p->data = x;
      p->next = 0;
      if(!IsEmpty())rear->next = p;
      else front = rear = p;    //当队列本来为空时,插入一个结点后,front和rear同时指向新结点
      rear = p;
      count++;
}

bool LinkedQueue::DeQueue()
{
      if (IsEmpty())return false;
      Node* p;           //出队列时,申请一个新结点指针暂存front,将front后移后,删除原来front指向的内存
      p = front;
      front = front->next;
      delete p;
      count--;
      return true;
}

bool LinkedQueue::Front(char &x)
{
      if (IsEmpty())return false;
      x = front->data;
      return true;
}

void LinkedQueue::ClearLinkedQueue()
{
      Node *p;
      p = front;
      while (front != 0)
      {
            p = front->next;
            delete front;
            front = p;
      }
      front = rear = 0;
      count = 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值