隊列:隊列是一種特殊的線性表,特殊之處在於它只允許在表的前端(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;
}
};