1.算法描述
a.数据结构与算法(Mark Allen Weiss)3.28双端队列的实现,在队列的两端都可以进行插入和删除工作,每种操作复杂度O(1).
b.没有头结点和尾结点的队列实现
c.循环数组的队列实现
2.算法实现
a.由于有复杂度的限制,和两端插入删除,故而使用数组是不适合的,必须使用链表,我这里使用的是双向链表,在两端操作的复杂度就一样的,非常方便
b.没有头尾结点实现队列,关键就是注意空队列的判断,在空队列情况下的插入删除操作。
c.循环数组就是在尾部循环的时候操作。
3.代码实现
a.双端队列
deque.h
//双端队列(两头都可以插入删除,故而使用的双向链表)
#ifndef DEQUE_H
#define DEQUE_H
template<class T>
struct Node{
Node* next;
Node* pre;
T data;
};
template<class T>
class Deque{
public:
Deque();
~Deque();
void push(T x); //插入双端队列的前端
T pop(); //删除前端元素并返回
T top() const; //前端元素
void inject(T x); //插入双端队列的尾端
T eject(); //从双端队列尾端删除并返回
T last() const; //尾端元素
int size() const;
void printDeque() const;
private:
Node<T> *first; //双端队列的前端
Node<T> *end; //双端队列的尾端
int length; //双端队列长度
void freeDeque();
};
#endif
deque.cpp
#include <iostream>
#include "deque.h"
#include "dsexceptions.h"
template<class T>
Deque<T>::Deque(){
first = new Node<T>;
end = new Node<T>;
first->next = end;
first->pre = NULL;
end->next = NULL;
end->pre = first;
length = 0;
}
template<class T>
Deque<T>::~Deque(){
freeDeque();
}
//插入双端队列的前端
template<class T>
void Deque<T>::push(T x){
Node<T> *r = first->next;
Node<T> *t = new Node<T>;
t->data = x;
first->next = t;
t->pre = first;
t->next = r;
r->pre = t;
length++;
}
//删除前端元素并返回
template<class T>
T Deque<T>::pop(){
if(first->next == end)
throw DequeOverFlowException();
Node<T> *r = first->next;
T data = r->data;
first->next = r->next;
r->next->pre = first;
delete r;
length--;
return data;
}
//前端元素
template<class T>
T Deque<T>::top() const{
if(first->next == end)
throw DequeOverFlowException();
return first->next->data;
}
//插入双端队列的尾端
template<class T>
void Deque<T>::inject(T x){
Node<T> *r = new Node<T>;
r->next = NULL;
r->pre = end;
end->data = x;
end->next = r;
end = r;
length++;
}
//从双端队列尾端删除并返回
template<class T>
T Deque<T>::eject(){
if(first->next == end)
throw DequeOverFlowException();
Node<T> *r = end->pre;
int data = r->data;
end->pre = r->pre;
r->pre->next = end;
delete r;
length--;
return data;
}
//尾端元素
template<class T>
T Deque<T>::last() const{
if(first->next == end)
throw DequeOverFlowException();
return end->pre->data;
}
template<class T>
int Deque<T>::size() const{
return length;
}
template<class T>
void Deque<T>::printDeque() const{
std::cout<<"[";
Node<T> *r = first->next;
while(r != end){
std::cout<<r->data<<" ";
r = r->next;
}
std::cout<<"]"<<std::endl;
}
template<class T>
void Deque<T>::freeDeque(){
Node<T> *r = first->next,*t;
while(r != end){
t = r;
r = r->next;
delete t;
}
delete first;
delete end;
}
dsexceptions.h
#ifndef DSEXCEPTIONS_H
#define DSEXCEPTIONS_H
class DequeOverFlowException{
public:
const char* what() const throw()
{
return "deque over flow exception, the size<=0 !\n";
}
};
#endif
main.cpp
#include <iostream>
#include "deque.cpp"
using namespace std;
int main(){
Deque<int> d;
cout<<"前端操作:"<<endl;
d.push(1);
d.push(2);
d.push(3);
d.printDeque();
cout<<d.size()<<endl;
cout<<d.top()<<endl;
d.pop();
cout<<d.top()<<endl;
cout<<"后端操作:"<<endl;
d.inject(5);
d.inject(6);
d.inject(7);
d.printDeque();
cout<<d.size()<<endl;
cout<<d.last()<<endl;
d.eject();
cout<<d.last()<<endl;
d.printDeque();
}
b.无头尾结点实现
queue.h
//链表实现队列,不含有头尾结点
#ifndef QUEUE_H
#define QUEUE_H
template<class T>
struct Node{
Node* next;
T data;
};
template<class T>
class Queue{
public:
Queue();
Queue(T a[], int n);
~Queue();
bool empty() const; //对是否为空
void enQueue(T x); //进队
T deQueue(); //出队
T queueFront() const; //返回队头元素
T queueRear() const; //返回队尾元素
int size() const; //队列大小
void printQueue() const;//打印队列
private:
Node<T>* front; //队头,允许删除的一端
Node<T>* rear; //队尾,允许插入的一端
int length; //队长度
void freeQueue(); //释放队列
};
#endif
queue.cpp
#include <iostream>
#include "queue.h"
#include "dsexceptions.h"
template<class T>
Queue<T>::Queue(){
front = new Node<T>;
front->next = NULL;
rear = front;
length = 0;
}
template<class T>
Queue<T>::Queue(T a[], int n){
if(n == 0) Queue();
else{
front = new Node<T>;
front->data = a[0];
front->next = NULL;
rear = front;
for(int i=1; i<n; i++){
Node<T>* r = new Node<T>;
r->data = a[i];
rear->next = r;
rear = r;
}
rear->next = NULL;
length = n;
}
}
template<class T>
Queue<T>::~Queue(){
freeQueue();
}
template<class T>
bool Queue<T>::empty() const{
if(length == 0)
return true;
return false;
}
template<class T>
void Queue<T>::enQueue(T x){
//注意不能使用rear == front判断,这样当队列为空,插入的元素始终在第一个位置
if(length == 0) front->data = x;//不含有队头队尾,故而都要存储元素
else{
Node<T>* r = new Node<T>;
r->data = x;
r->next = NULL;
rear->next = r;
rear = r;
}
length++;
}
template<class T>
T Queue<T>::deQueue(){
T data;
if(length == 0){
throw QueueEmptyException();
}else{
data = front->data;
//当为1的时候front==rear,我们不能将其删除,要保留front rear
if(length == 1){
front->data = 0;
}else{
Node<T>* r = front;
front = r->next;
delete r;
}
length--;
}
return data;
}
template<class T>
T Queue<T>::queueFront() const{
if(length == 0){
throw QueueEmptyException();
}else{
return front->data;
}
}
template<class T>
T Queue<T>::queueRear() const{
if(length == 0){
throw QueueEmptyException();
}else{
return rear->data;
}
}
template<class T>
int Queue<T>::size() const{
return length;
}
template<class T>
void Queue<T>::printQueue() const{
Node<T>* r = front;
std::cout<<"[";
while(r){
//当front==rear的时候还有可能是空,此时没有删除front,rear
if(length == 0) break;
std::cout<<r->data<<" ";
r = r->next;
}
std::cout<<"]"<<std::endl;
}
template<class T>
void Queue<T>::freeQueue(){
Node<T>* r = front, *t;
while(r){
t = r;
r = r->next;
delete t;
}
}
esexceptions.h
#ifndef DSEXCEPTIONS_H
#define DSEXCEPTIONS_H
class QueueEmptyException{
public:
const char* what() const throw()
{
return "queue empty exception, the size<=0 !\n";
}
};
#endif
main.cpp
#include <iostream>
#include "queue.cpp"
using namespace std;
int main(){
try{
Queue<int> q;
cout<<q.empty()<<endl;
cout<<q.size()<<endl;
q.printQueue();
q.enQueue(1);
q.enQueue(2);
cout<<q.size()<<endl;
cout<<"出队"<<q.deQueue()<<endl;
cout<<q.size()<<endl;
q.printQueue();
cout<<"出队"<<q.deQueue()<<endl;
cout<<q.size()<<endl;
//q.deQueue();
int a[] = {1,2,3,4,5};
Queue<int> p(a, 5);
cout<<p.empty()<<endl;
cout<<p.size()<<endl;
p.printQueue();
p.deQueue();
p.deQueue();
p.deQueue();
p.enQueue(6);
p.printQueue();
cout<<p.size()<<endl;
cout<<"出队"<<p.deQueue()<<endl;
cout<<p.size()<<endl;
p.printQueue();
}catch(QueueEmptyException &e){
cout<<e.what();
}
return 0;
}
c.循环队列实现
queue.h
//链表实现队列,不含有头尾结点
#ifndef QUEUE_H
#define QUEUE_H
template<class T>
class Queue{
public:
Queue(int n);
Queue(T a[], int n, int length);
~Queue();
bool empty() const; //对是否为空
void enQueue(T x); //进队
T deQueue(); //出队
T queueFront() const; //返回队头元素
T queueRear() const; //返回队尾元素
int size() const; //队列大小
void printQueue() const;//打印队列
private:
int front; //队头,允许删除的一端
int rear; //队尾,允许插入的一端
int max; //队列固定长度
int length; //队长度
T* array; //队列数组
};
#endif
queue.cpp
#include <iostream>
#include "queue.h"
#include "dsexceptions.h"
template<class T>
Queue<T>::Queue(int n){
array = new T[n];
length = 0;
max = n;
rear = front = -1;
}
template<class T>
Queue<T>::Queue(T a[], int n, int len){
if(n>= len)
throw QueueOverFlowException();
array = new T[len];
for(int i=0; i<n; i++)
array[i] = a[i];
length = n;
max = len;
front = 0;
rear = n-1;
}
template<class T>
Queue<T>::~Queue(){
delete[] array;
}
template<class T>
bool Queue<T>::empty() const{
if(length == 0)
return true;
return false;
}
template<class T>
void Queue<T>::enQueue(T x){
if(length == max) //1.队满
throw QueueOverFlowException();
if(length == 0){ //2.队空
rear++;
if(rear > max-1) rear %= max;
array[rear] = x;
front++;//此时队不空,front和rear指向同一个位置
}
else{ //3.其他
rear ++;
if(rear > max-1) rear %= max;
array[rear] = x;
}
length++;
}
template<class T>
T Queue<T>::deQueue(){
T data;
if(length == 0){
throw QueueEmptyException();
}else{
data = array[front];
if(length == 1) front = rear = -1; //将front,rear置为-1表示为空
front++;
if(front > max-1) front %= max;
length--;
}
return data;
}
template<class T>
T Queue<T>::queueFront() const{
if(length == 0){
throw QueueEmptyException();
}else{
return array[front];
}
}
template<class T>
T Queue<T>::queueRear() const{
if(length == 0){
throw QueueEmptyException();
}else{
return array[rear];
}
}
template<class T>
int Queue<T>::size() const{
return length;
}
template<class T>
void Queue<T>::printQueue() const{
int a = front, b = length;
std::cout<<"[";
while(b){
b--;
std::cout<<array[a++]<<" ";
if(a > max-1) a %= max;
}
std::cout<<"]"<<std::endl;
}
dsexceptions.h
#ifndef DSEXCEPTIONS_H
#define DSEXCEPTIONS_H
class QueueEmptyException{
public:
const char* what() const throw()
{
return "queue empty exception, the size<=0 !\n";
}
};
class QueueOverFlowException{
public:
const char* what() const throw()
{
return "queue over flow exception, the size over the capacity !\n";
}
};
#endif
main.cpp
#include <iostream>
#include "queue.cpp"
using namespace std;
int main(){
try{
int a[] = {1,2,3,4,5};
Queue<int> p(a, 5, 7);
cout<<p.empty()<<endl;
cout<<p.size()<<endl;
p.printQueue();
p.deQueue();
p.enQueue(6);
p.enQueue(7);
p.enQueue(8);
//p.enQueue(9);//入队超出capacity
p.printQueue();
cout<<p.size()<<endl;
cout<<"出队"<<p.deQueue()<<endl;
cout<<p.size()<<endl;
p.printQueue();
}catch(QueueEmptyException &e){
cout<<e.what();
}catch(QueueOverFlowException &e){
cout<<e.what();
}
return 0;
}