【慢速学数据结构】队列篇
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那样,将所有的内容重新复制到新的内存中。
相关文章推荐
- C#数据结构之顺序表(SeqList)实例详解
- Lua教程(七):数据结构详解
- 解析从源码分析常见的基于Array的数据结构动态扩容机制的详解
- C#数据结构之队列(Quene)实例详解
- C#数据结构揭秘一
- C#数据结构之单链表(LinkList)实例详解
- 数据结构之Treap详解
- 用C语言举例讲解数据结构中的算法复杂度结与顺序表
- C#数据结构之堆栈(Stack)实例详解
- C#数据结构之双向链表(DbLinkList)实例详解
- JavaScript数据结构和算法之图和图算法
- Java数据结构及算法实例:冒泡排序 Bubble Sort
- Java数据结构及算法实例:插入排序 Insertion Sort
- Java数据结构及算法实例:考拉兹猜想 Collatz Conjecture
- java数据结构之java实现栈
- java数据结构之实现双向链表的示例
- Java数据结构及算法实例:选择排序 Selection Sort
- Java数据结构及算法实例:朴素字符匹配 Brute Force
- Java数据结构及算法实例:汉诺塔问题 Hanoi
- Java数据结构及算法实例:快速计算二进制数中1的个数(Fast Bit Counting)