`
hao3100590
  • 浏览: 128646 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

多种队列的实现

阅读更多

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;
}
 

 

 

 

 

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics