FIFO 先进先出
设计一个循环队列实现。 循环队列是一种线性数据结构,其操作表现基于 FIFO(先进先出)原则并且队尾被连接在队首之后以形成一个循环。它也被称为“环形缓冲器”。
设计
要求能够在头进行删除,尾进行插入==>带尾指针循环双链表
实现
struct Node
{ // 链表结点数据结构
int val;
Node *next;
Node *prev;
Node() : next(nullptr), prev(nullptr) {}
Node(int _val) : val(_val), next(nullptr), prev(nullptr) {}
Node(int _val, Node *_next) : val(_val), next(_next), prev(nullptr) {}
};
struct LinkedList
{ // 链表数据结构
Node *tail; // 虚拟尾指针
int capacity; // 容量
int size; // 当前大小
LinkedList(int k) : tail(new Node()), capacity(k), size(0)
{
tail->next = tail;
tail->prev = tail;
}
Node *getFront()
{
return tail->next;
}
Node *getRear()
{
return tail->prev;
}
// 插入尾部(tail->prev)
void addTail(Node *cur)
{
cur->next = tail;
cur->prev = tail->prev;
tail->prev->next = cur;
tail->prev = cur;
++size;
}
// 删除头部(tail->next)
Node *delHead()
{
Node *rst = tail->next;
rst->next->prev = tail;
tail->next = tail->next->next;
--size;
return rst;
}
bool empty()
{
return size == 0;
}
bool full()
{
return size == capacity;
}
};
class MyCircularQueue
{
private:
LinkedList q;
public:
MyCircularQueue(int k) : q(k) {}
// 插入
bool enQueue(int value)
{
if (q.full())
{ // 满了无法插入,size == capacity,包括了初始容量0的情况
return false;
}
Node *cur = new Node(value);
q.addTail(cur);
return true;
}
// 删除
bool deQueue()
{
if (q.empty())
{
return false;
}
Node *cur = q.delHead();
delete cur;
return true;
}
int Front()
{
if (q.empty())
{
return -1;
}
return q.getFront()->val;
}
int Rear()
{
if (q.empty())
{
return -1;
}
return q.getRear()->val;
}
bool isEmpty()
{
return q.empty();
}
bool isFull()
{
return q.full();
}
};
简单写法:
struct Node
{
int val_;
Node *prev_;
Node *next_;
Node() : val_(0), prev_(nullptr), next_(nullptr) {}
Node(int _val) : val_(_val), prev_(nullptr), next_(nullptr) {}
Node(int _val, Node *_prev, Node *_next) : val_(_val), prev_(_prev), next_(_next) {}
};
class MyCircularQueue
{
private:
int capcity_;
int size_;
Node *dummyTail_;
public:
MyCircularQueue(int k) : capcity_(k), size_(0), dummyTail_(new Node())
{
dummyTail_->next_ = dummyTail_;
dummyTail_->prev_ = dummyTail_;
}
bool enQueue(int value)
{
if (isFull())
{
return false;
}
Node *tmp = new Node(value, dummyTail_->prev_, dummyTail_);
dummyTail_->prev_->next_ = tmp;
dummyTail_->prev_ = tmp;
size_++;
return true;
}
bool deQueue()
{
if (isEmpty())
{
return false;
}
Node *tmp = dummyTail_->next_;
dummyTail_->next_ = tmp->next_;
tmp->next_->prev_ = dummyTail_;
size_--;
delete tmp;
return true;
}
int Front()
{
if (isEmpty())
{
return -1;
}
return dummyTail_->next_->val_;
}
int Rear()
{
if (isEmpty())
{
return -1;
}
return dummyTail_->prev_->val_;
}
bool isEmpty() { return size_ == 0; }
bool isFull() { return capcity_ == size_; }
};