队列的另一种存储方式是链表,可以用带头结点的单链表来表示;队列的头指针front指向单链表的头结点,队列的尾指针rear指向单链表的最后一个节点。
出队就是删除第一个元素节点,入队就是在表维增加一个节点;其中链表式的队列模版中有两个数据成员,分别是队头指针front和队尾指针rear,其初始值都指向头节点,头节点后没有元素,表示空队列;
简单实现了下
#ifndef NODE_h
#define NODE_h
#define NULL 0
template<class T>
struct Node{
Node<T>* next;
T data;
Node(){
next=NULL;
}
Node(T e,Node<T>* p=NULL){
next=p;
data=e;
}
};
#endif
#ifndef GUARD_SEQQUEUE_h
#define GUARD_SEQQUEUE_h
#include"Node.h"
#include<iostream>
#include<cassert>
template<class T>
class SeqQueue{
public:
explicit SeqQueue();
virtual ~SeqQueue();
//判断队空
bool IsEmpty()const;
//元素个数
int GetLength()const;
//入队
void EnQueue(const T& e);
//出队
T DelQueue();
//取对头元素
T GetFront();
//清空队列
void Clear();
private:
//链式存储不需要考虑长度,也不需要数据元素,这些可以通过Node去构造
Node<T>* front;
Node<T>* rear;
};
template<class T>
SeqQueue<T>::SeqQueue(){
front=rear=new Node<T>;
}
//销毁链式队列中所有的节点,并释放头节点
template<class T>
SeqQueue<T>::~SeqQueue (){
Clear();
delete front;
}
template<class T>
int SeqQueue<T>::GetLength()const{
Node<T>* p=front->next;
int count=0;
for(p;p!=NULL;p->next){
++count;
}
return count;
}
//头结点后没有元素节点表示队空
template<class T>
bool SeqQueue<T>::IsEmpty()const{
return front->next==NULL;
}
//入队:先加节点,再移动rear指针
template<class T>
void SeqQueue<T>::EnQueue(const T& e){
Node<T>* p;
p=new Node<T>(e,NULL);
rear->next=p;
rear=rear->next;
}
//出队
template<class T>
T SeqQueue<T>::DelQueue(){
assert(!IsEmpty());
T e;
Node<T>* p=front->next;
e=p->data;
front->next=p->next;
delete p;
return e;
}
//取队头元素
template<class T>
T SeqQueue<T>::GetFront(){
assert(!IsEmpty());
T e;
e=front->next->data;
return e;
}
//清空列表,只保留头结点,并且使头指针和尾指针都指向头节点
template<class T>
void SeqQueue<T>::Clear(){
Node<T>* p=front->next;
while(p!=NULL){
front->next=p->next;
delete p;
p=front->next;
}
rear=front;
}
#endif
#include"SeqQueue.h"
#include<iostream>
using namespace std;
int main(){
int i;
SeqQueue<char> que; //构造一个空链队
char str1[]="abcdefghijklmnop"; //17个元素,包括串结束符
for(i=0;i<17;i++) que.EnQueue(str1[i]);
for(i=0;i<17;i++) cout<<que.DelQueue(); //先进先出
cout<<endl;
if(que.IsEmpty()) cout<<"队空"<<endl;
return 0;
}