您的位置:首页 > 理论基础 > 数据结构算法

【慢速学数据结构】队列篇

2016-07-15 01:38 447 查看

概述

队列ADT我相信大家都很清楚,就是FIFO嘛。

这一篇,关键讲队列怎么实现。

实现

循环数组实现。

template<typename T>
class Queue_array
{
public:
Queue_array(int maxsize = 10) : maxsize_(maxsize),
size_(0), front_(1), rear_(0)
{
pa_ = new T[maxsize_];// 初始化数组,默认大小为10
}
virtual ~Queue_array()
{
delete[] pa_;
}

public:
void push(const T& x)
{
if (isFull())
return;

size_++;
rear_++;
rear_ %= maxsize_;// 让rear在将要越界的时候,回到0,从而实现循环

*(pa_ + rear_) = x;
}
void pop()
{
size_--;
front_++;
front_ %= 10;// 不要忘了,这里也要加
}
const T getFront()
{
return *(pa_ + front_);
}
const int getSize() const
{
return size_;
}
bool isEmpty() const
{
return size == 0;
}
bool isFull() const
{
return size_ == maxsize_;
}

private:
int front_, rear_;
T* pa_;
int size_;
int maxsize_;
};


链表实现

template<typename T>
class Queue_list {
public:
typedef struct list {
T data;
list *next;
list(T x) : data(x), next(nullptr) {}
} ListNode;

Queue_list(int maxsize = 10) : size_(0), maxsize_(maxsize) {
front_ = rear_ = new ListNode(0);// 初始化,front和rear都指向同一个结点
}

virtual ~Queue_list() {
while( front_ != rear_) {
ListNode* t = front_->next;
delete front_;
front_ = t;
}
delete rear_;
};
public:
// 插到rear现在所在的位置,并且新增一个结点让rear指向它
void push( const T& x) {
size_++;
rear_->data = x;
rear_->next = new ListNode(0);
rear_ = rear_->next;
}

// 删除front现在指向的结点,将front指向下一个结点
void pop() {
size_--;
ListNode *t = front_;
front_ = front_->next;
delete t;
}

const T getFront() {
return front_->data;
}

const int getSize() const {
return size_;
}

bool isEmpty() const {
return front == rear;
}

// 链表实现可以不考虑队列满的情况
private:
ListNode *front_, *rear_;
int size_;
int maxsize_;
};


测试用例:

int main() {
{
Queue_list<int> q;
for(auto i = 0; i<10; i++)
q.push(i);
q.pop();
assert(9 == q.getSize());
assert(1 == q.getFront());
q.push(10);
q.pop();
assert(2 == q.getFront());
}

{
Queue_array<int> q;
for(auto i = 0; i<10; i++)
q.push(i);
q.pop();
assert(9 == q.getSize());
assert(1 == q.getFront());
q.push(10);
q.pop();
assert(2 == q.getFront());
}

std::cout << "All test cases pass";
return 0;
}


应用

来学习一下STL里的deque,cppreference里对它的大概描述是:

deque(double end queue 双端队列),随机访问时间O(1),插入头和尾结点的时间是O(1),普通插入的时间是O(N)。它的存储是由多个固定大小的数组组成,而且在动态扩充大小的时候效率很高,不会像vector那样,将所有的内容重新复制到新的内存中。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  数据结构