队列:队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头
以下是单链表实现:
class Queue{
List l;
public:
Queue(List l):l(l){}
Queue& push(const T& d){l.push_back(d);return *this;}//链表尾部插入
T pop(){T t=front();l.dele1(1);}//链表头部删除
const T& front()const{return l.front();}
const T& back()const{return l.back();}
int size()const{}
void clear(){l.clear();}
bool empty()const{return l.empty();}
bool full()const{return false;}
void travel(){l.travel();}
};
链表dele函数:
int dele1(int pos){
if(pos<=0||pos>size())
return 1;
Node*& pn=getptr(pos-1);
Node* temp=pn;
pn=pn->next;
delete temp;
return 0;
}
链表getptr函数:
Node*& List::getptr(int pos)//返回第K个成员的成员指针引用!
{
if(pos>size()||pos<0) return head;
if(pos==0) return head;
Node* p=head;
for(int i=1;i<pos;i++)
{
p=p->next;
}
return (*p).next;
}
顺序队列:
1.当队列空时,设置front=rear=-1
2.当第一个元素入队时,f=r=0;同时改变了两个下标
3,进行入队,出队操作时,front,rear也随之变化
4,当入队元素个数超过数组大小(包括出队元素),rear下标越界,数组溢出。假溢出。
class Queue{ //顺序队列,数组实现
//初始,f=r=-1,f指向第一个元素,r指向最后一个元素,会发生假溢出现象
T *element;
int len;
int f;
int r;
public:
Queue(int len):f(-1),r(-1),len(len){element=new T[len];}
bool isempty(){return len==0;}
void enqueue(T x){
if(f==-1 && r==-1)
{ element[0]=x;
f++;
r++;
return;
}
element[++r]=x;
}
T dequeue(){
return element[f++];
}
void travel()
{
for(int i=f;i!=r+1;i++)
cout<<element[i]<<' ';
cout<<endl;
}
~Queue(){delete [] element;}
};
顺序循环队列:
把所有的存储单元构造成一个逻辑上首尾相连的循环队列。
1.队头队尾元素按照如下规律变化,front=(front+1%)size,rear=(rear+1)%size,因此下标范围为0~size-1,不会出现假溢出现象
2.约定rear是下一个入队的元素位置,队列空即f==r,初始空队列f==r==0;不需要同时改变两个下标。
template<typename T>
class Seqqueue{ //顺序循环队列
T* element;//动态数组存储队列的数据元素
int len;
int f;
int r;
public:
Seqqueue(int l)
{
f=0;
r=0;
len=l;
element=new T[l];
}
~Seqqueue(){delete[] element;}
void enqueue(T a){
if(f == (r+1)%len)//队列已经满了,重新申请2倍空间
{
T* temp=element;
element=new T[2*len];
int i=f,j=0;
while(i!=r)//挨个复制
{
element[j]=temp[i];
i=(i+1)%len;
j++;
}
f=0;
r=j;
len*=2;
}
element[r]=a;
r=(r+1)%len;
}
T dequeue(){
if(!isempty())
{
T x=element[f];
f=(f+1)%len;
return x;
}
throw "空队列,怎么取?";
}
T top(){return element[f];}
bool isempty(){return f==r ;}
void show(){
for(int i=f;i!=r;i=(i+1)%len)
{
cout << element[i] <<' ';
}
cout << endl;
}
};
优先队列:
定义:若一个队列的每一个元素都有一个优先级,每次出队的都是具有最高优先级的元素,那么这个队列为优先队列。
可采用顺序存储方式,插入入队尾,时间为O(1),出队则要遍历队列中优先级最高的元素删除并把该元素至队尾的元素都向前移动,队列长度为n,时间为O(n)
也可以采用排序的顺序表表示优先队列,元素按照优先级排序存储,出队(时间为O(1)),入队则插入合适的位置。
template<typename T>
class priority__queue//单链表实现的优先队列
{
list<T> l;
public:
priority__queue(){}
bool isempty(){return l.empty();}
void enqueue(T x){
l.push_back(x);
l.sort();
}
T dequeue(){
if(!l.empty())
{
T x=l.front();
l.pop_front();
return x;
}
throw "空";javascript:;
}
T top(){return l.front();}
};
上述是使用C++自带模板List实现的优先队列。
顺序存储结构实现的优先队列:
template<typename T>
class pqueque//顺序存储实现优先队列
{
T* element;
int len;
int f;
int r;
public:
pqueque(int l){f=0;r=0;len=l;element=new T[len];}
void enqueue(T a)
{
if(f==(r+1)%len)
{
T* temp=element;
element=new T[2*len];
int i=f;
int j=0;
while(i!=r)
{
element[j++]=temp[i];
i=(i+1)%len;
}
f=0;
r=j;
len*=2;
}
element[r]=a;
r=(r+1)%len;
}
T dequeue()
{
if(f==r)
throw "空队列";
T tmp=element[f];
int flag=f;
for(int i=f;i!=r;i=(i+1)%len)//找到最大元素
{
if(element[i]>tmp)
flag=i;
}
tmp = element[flag];
while((flag+1)&len != r)//移动元素
{
element[flag]=element[(flag+1)%len];
flag=(flag+1)%10;
}
r=flag;//队尾往前走一个
return tmp;
}
};