算法导论 顺序循环双向队列
来源:互联网 发布:分班软件 课程 编辑:程序博客网 时间:2024/09/21 09:20
顺序循环双向队列
1. 什么是双向队列?
算法导论原题:
10.1-5
Whereas a stack allows insertion and deletion of elements at only one end, and a queue allows insertion at one end and deletion at the other end, a deque (double-ended queue) allows insertion and deletion at both ends. Write four O(1) time procedures to insert elements into and delete elements from both ends of a deque implemented by an array.
译:栈只允许在一端插入和删除元素,队列只允许在一端插入和在另一端删除,一个deque(double-ended queue,双向队列)允许在两端插入和删除。写出4个运行时间为O(1)的过程,分别在两端插入和删除元素,该列队是用一个数组实现的。
2. 双向队列如何实现?
顺序双向循环队列只是在原来的顺序循环队列基础上,增加了队列头的插入和队列尾的删除操作。只要写过普通队列的操作,双向队列的操作也是不难写的,并没有多大难度。建议读者们自己尝试动手写一下。
3. 双向队列的实现(C++代码)
//SequeDeQueue.h#pragma once#include <assert.h>template<typename ElemType>class SequeDeQueue{public: SequeDeQueue(unsigned int size); bool HeadDeQueue(ElemType* elem); bool TailDeQueue(ElemType* elem); bool HeadEnQueue(const ElemType& elem); bool TailEnQueue(const ElemType& elem); bool Empty(); bool Visit(ElemType* elem, unsigned int pos) const;private: ElemType* m_array; unsigned int m_tail; unsigned int m_head; unsigned int m_size;};template<typename ElemType>bool SequeDeQueue<ElemType>::TailEnQueue(const ElemType& elem){ if ( (m_tail + 1 + m_size) % m_size == m_head) { assert(false && "Error: SequeDeQueue is overflow!"); return false; } else { m_array[m_tail] = elem; m_tail = (m_tail + 1 + m_size) % m_size; return true; }}template<typename ElemType>bool SequeDeQueue<ElemType>::HeadEnQueue(const ElemType& elem){ if ( (m_head - 1 + m_size) % m_size == m_head) { assert(false && "Error: SequeDeQueue is overflow!"); return false; } else { m_array[m_head] = elem; m_head = (m_head - 1 + m_size) % m_size; return true; }}template<typename ElemType>bool SequeDeQueue<ElemType>::TailDeQueue(ElemType* elem){ if (Empty()) { assert(false && "Error: SequeDeQueue is underflow!"); return false; } else { m_tail = (m_tail - 1 + m_size) % m_size; *elem = m_array[m_tail]; return true; }}template<typename ElemType>bool SequeDeQueue<ElemType>::HeadDeQueue(ElemType* elem){ if (Empty()) { assert(false && "Error: SequeDeQueue is underflow!"); return false; } else { m_head = (m_head + 1 + m_size) % m_size; *elem = m_array[m_head]; return true; }}template<typename ElemType>bool SequeDeQueue<ElemType>::Visit(ElemType* elem, unsigned int pos) const{ if (pos >= m_size || pos < 0) { assert(false && "Error: Visit Pos is out range of array!"); return false; } *elem = m_array[pos]; return true;}template<typename ElemType>bool SequeDeQueue<ElemType>::Empty(){ return ((m_head + 1 + m_size) % m_size == m_tail) ? true : false;}template<typename ElemType>SequeDeQueue<ElemType>::SequeDeQueue(unsigned int size) :m_array(new ElemType[size]),m_tail(0),m_head(size-1),m_size(size){ memset(m_array,0,sizeof(ElemType)*size);}
//Util.h#pragma oncenamespace Util{ template<typename T> void PrintMemory(const T& dateStruct, unsigned int size) { cout << "PrintMemory: "; for (int i = 0; i != size; i++) { ElemType tempElem; dateStruct.Visit(&tempElem,i); printf("%d ",tempElem); } printf("\n"); printf("\n"); }}
//main.cpp#include "Util.h"#include "SequeDeQueue.h"#include <iostream>using namespace std;typedef int ElemType;int main(){ const int QUEUE_SIZE = 10; SequeDeQueue<int> testSequeDeQueue(QUEUE_SIZE); cout << "testSequeDeQueue is " << (testSequeDeQueue.Empty() ? "Empty." : "Not Empty.") << endl; Util::PrintMemory(testSequeDeQueue,QUEUE_SIZE); for (int i = 1; i != 4; i++) { testSequeDeQueue.HeadEnQueue(i); cout << "HeadEnQueue:" << i << endl; cout << "testSequeDeQueue is " << (testSequeDeQueue.Empty() ? "Empty." : "Not Empty.") << endl; Util::PrintMemory(testSequeDeQueue,QUEUE_SIZE); } for (int i = 4; i != 7; i++) { testSequeDeQueue.TailEnQueue(i); cout << "TailEnQueue:" << i << endl; cout << "testSequeDeQueue is " << (testSequeDeQueue.Empty() ? "Empty." : "Not Empty.") << endl; Util::PrintMemory(testSequeDeQueue,QUEUE_SIZE); } for (int i = 0; i != 2; i++) { ElemType tempElem; testSequeDeQueue.HeadDeQueue(&tempElem); cout << "HeadDeQueue:" << tempElem << endl; cout << "testSequeDeQueue is " << (testSequeDeQueue.Empty() ? "Empty." : "Not Empty.") << endl; Util::PrintMemory(testSequeDeQueue,QUEUE_SIZE); } for (int i = 0; i != 4; i++) { ElemType tempElem; testSequeDeQueue.TailDeQueue(&tempElem); cout << "TailDeQueue:" << tempElem << endl; cout << "testSequeDeQueue is " << (testSequeDeQueue.Empty() ? "Empty." : "Not Empty.") << endl; Util::PrintMemory(testSequeDeQueue,QUEUE_SIZE); } return 0;}
4. 程序运行结果
testSequeDeQueue is Empty.
PrintMemory: 0 0 0 0 0 0 0 0 0 0HeadEnQueue:1
testSequeDeQueue is Not Empty.
PrintMemory: 0 0 0 0 0 0 0 0 0 1HeadEnQueue:2
testSequeDeQueue is Not Empty.
PrintMemory: 0 0 0 0 0 0 0 0 2 1HeadEnQueue:3
testSequeDeQueue is Not Empty.
PrintMemory: 0 0 0 0 0 0 0 3 2 1TailEnQueue:4
testSequeDeQueue is Not Empty.
PrintMemory: 4 0 0 0 0 0 0 3 2 1TailEnQueue:5
testSequeDeQueue is Not Empty.
PrintMemory: 4 5 0 0 0 0 0 3 2 1TailEnQueue:6
testSequeDeQueue is Not Empty.
PrintMemory: 4 5 6 0 0 0 0 3 2 1HeadDeQueue:3
testSequeDeQueue is Not Empty.
PrintMemory: 4 5 6 0 0 0 0 3 2 1HeadDeQueue:2
testSequeDeQueue is Not Empty.
PrintMemory: 4 5 6 0 0 0 0 3 2 1TailDeQueue:6
testSequeDeQueue is Not Empty.
PrintMemory: 4 5 6 0 0 0 0 3 2 1TailDeQueue:5
testSequeDeQueue is Not Empty.
PrintMemory: 4 5 6 0 0 0 0 3 2 1TailDeQueue:4
testSequeDeQueue is Not Empty.
PrintMemory: 4 5 6 0 0 0 0 3 2 1TailDeQueue:1
testSequeDeQueue is Empty.
PrintMemory: 4 5 6 0 0 0 0 3 2 1
- 算法导论 顺序循环双向队列
- 算法导论 顺序循环队列
- 双向循环队列解析
- 双向循环队列解析
- 双向循环队列
- 双向循环队列
- 双向循环队列
- 顺序队列的基本算法及循环队列
- 算法导论阅读顺序
- 算法导论-----队列
- 算法导论-优先级队列
- 算法导论—队列
- 《算法导论》优先队列
- 算法导论 循环单链表
- 算法导论 循环双链表
- 算法导论 顺序双向栈——两个栈共享同一存储空间
- SeqQueue--顺序循环队列
- 顺序循环队列
- 浅谈JS闭包
- OC所有的方法是都是虚方法
- Guava并发:ListenableFuture使用介绍以及示例
- C语言知识点复习 一
- Windows共享漏洞
- 算法导论 顺序循环双向队列
- poj 2886 Who Gets the Most Candies? 【线段树单点更新 + 反素数】
- JDK源码阅读之Collection集合接口
- C++Primer第五版 7.5.6节练习
- HDU 1811 Rank of Tetris(拓扑排序确定排名,排名有重复的情况)
- Delphi打开长于260个字符的网页
- (WMI)信息可能损坏"错误的修复
- NSDate将日期类字符串Tue Sep 15 19:00:03 +0800 2015转化为09-15 19:52日期类型的格式
- 这个自媒体的访问量突破了100亿,我们能从中学到什么