生活随笔
收集整理的這篇文章主要介紹了
五、队列(Queue)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
一、概述
隊列(queue): 只允許在一端進行插入 (隊尾) 操作,而在另一端 (隊頭) 進行刪除操作的線性表。 隊頭:刪除操作的一端——front 隊尾:插入操作的一端——rear
特點:先進先出(First In First Out) 其他常用隊列:循環隊列、阻塞隊列、并發隊列。
二、隊列的抽象數據類型
ADT 隊列 (Queue)
Data同線性表。元素具有相同的類型,相鄰元素具有前驅和后繼關系
OpreationInitQueue(*Q): 初始化操作,建立一個空隊列Q。DestroyQueue(*Q): 若隊列Q存在,則銷毀它。ClearQueue(*Q): 將隊列Q清空。QueueEmpty(Q): 若隊列為空,返回true,否則返回false。GetHead(Q,*e): 若隊列Q存在且非空
二、C++隊列的方法
back() ——返回最后一個元素;empty() ——如果隊列空則返回true,否則返回false;front() ——返回第一個元素;pop() ——從隊頭刪除第一個元素;push() ——在隊尾插入一個元素;size() ——返回隊列中元素的大小;
#include <iostream>
#include <queue>
using namespace std
; int main ( )
{ queue
< int > que
; for ( int i
= 0 ; i
< 50 ; i
++ ) { que
. push ( i
) ; } cout
<< "the size of queue:" << que
. size ( ) << endl
; while ( ! que
. empty ( ) ) { cout
<< "the front element of queue:" << que
. front ( ) << " " ; cout
<< "the rear element of queue:" << que
. back ( ) << endl
; que
. pop ( ) ; } cout
<< "the size of queue:" << que
. size ( ) << endl
; return 0 ;
}
三、實現
1、順序隊列——數組實現
順序隊列需事先確定隊列的大小,不支持動態分配存儲空間,所以插入和刪除元素比較省時,但是會造成空間的浪費。
解決方法:循環隊列 =》解決空間浪費的問題 循環隊列的實現:
#include <iostream>
using namespace std
; const int MAXSIZE
= 1000 ;
typedef int ELEMTYPE
;
const int N
= 10 ;
typedef struct { ELEMTYPE data
[ MAXSIZE
] ; int head
; int rear
;
} Queue
; Queue Q
;
void initQueue ( Queue
& Q
) ;
void printQueue ( Queue
& Q
) ;
bool isQueueEmpty ( Queue
& Q
) ;
bool isQueueFull ( Queue
& Q
) ;
bool EnQueue ( Queue
& Q
, ELEMTYPE e
) ;
bool DeQueue ( Queue
& Q
, ELEMTYPE
& e
) ; int main ( )
{ for ( int i
= 0 ; i
< N
; i
++ ) { EnQueue ( Q
, i
) ; } printQueue ( Q
) ; return 0 ;
} void initQueue ( Queue
& Q
)
{ Q
. head
= 0 ; Q
. rear
= 0 ;
}
void printQueue ( Queue
& Q
)
{ ELEMTYPE e
; while ( ! isQueueEmpty ( Q
) ) { DeQueue ( Q
, e
) ; cout
<< e
<< " " ; } cout
<< endl
;
}
bool isQueueEmpty ( Queue
& Q
)
{ if ( Q
. head
== Q
. rear
) return true ; else return false ;
}
bool isQueueFull ( Queue
& Q
)
{ if ( ( Q
. rear
+ 1 ) % MAXSIZE
== Q
. head
) return true ; else return false ;
}
bool EnQueue ( Queue
& Q
, ELEMTYPE e
)
{ if ( isQueueFull ( Q
) ) return false ; Q
. rear
= ( Q
. rear
+ 1 ) % MAXSIZE
; Q
. data
[ Q
. rear
] = e
; return true ;
}
bool DeQueue ( Queue
& Q
, ELEMTYPE
& e
)
{ if ( isQueueEmpty ( Q
) ) return false ; Q
. head
= ( Q
. head
+ 1 ) % MAXSIZE
; e
= Q
. data
[ Q
. head
] ; return true ;
}
2、鏈式隊列——鏈表實現
可以不需要事先知道隊列的大小,支持動態和釋放空間,但是插入和刪除操作比較耗時
#include <iostream>
using namespace std
;
struct NODE
{ int data
; NODE
* next
; NODE
* pre
;
} ;
class QUEUE
{
private : NODE
* front
; NODE
* tail
; unsigned size
;
public : QUEUE ( ) ; ~ QUEUE ( ) { } ; void initialize ( ) ; void enqueue ( int n
) ; void dequeue ( ) ; int get_front ( ) ; void clear ( ) ; int get_size ( ) ; bool isempty ( ) ; void display_queue ( ) ;
} ;
QUEUE
:: QUEUE ( )
{ initialize ( ) ;
}
void QUEUE
:: initialize ( )
{ front
= new NODE ( ) ; tail
= new NODE ( ) ; front
- > data
= tail
- > data
= 0 ; front
- > pre
= tail
- > next
= NULL ; front
- > next
= tail
; tail
- > pre
= front
; size
= 0 ;
}
void QUEUE
:: enqueue ( int n
)
{ NODE
* new_ele
= new NODE ( ) ; new_ele
- > data
= n
; tail
- > pre
- > next
= new_ele
; new_ele
- > next
= tail
; new_ele
- > pre
= tail
- > pre
; tail
- > pre
= new_ele
; size
++ ;
}
void QUEUE
:: dequeue ( )
{ if ( isempty ( ) ) { cout
<< "queue is empty" << endl
; return ; } NODE
* temp
= front
- > next
; front
- > next
= temp
- > next
; temp
- > next
- > pre
= front
; delete ( temp
) ; size
-- ;
}
int QUEUE
:: get_front ( )
{ if ( front
- > next
!= tail
) return front
- > next
- > data
; else cout
<< "empty queque" << endl
; return - 1 ;
}
void QUEUE
:: clear ( )
{ NODE
* temp
= front
; while ( temp
!= tail
) { NODE
* del_data
= temp
; temp
= temp
- > next
; delete ( del_data
) ; } initialize ( ) ;
}
int QUEUE
:: get_size ( )
{ return size
;
}
void QUEUE
:: display_queue ( )
{ NODE
* temp
= front
- > next
; while ( temp
!= tail
) { cout
<< temp
- > data
<< " " ; temp
= temp
- > next
; } if ( isempty ( ) ) cout
<< "queue is empty" << endl
; else cout
<< endl
;
}
bool QUEUE
:: isempty ( )
{ return front
- > next
== tail
;
}
int main ( int argc
, char const * argv
[ ] )
{ QUEUE que
; return 0 ;
}
3、循環隊列
關鍵:判斷隊列是空對還是滿隊 空:head == tail 滿:(tail+1)%n == head 當循環隊列滿隊時,tail指針指向的位置實際并沒有存儲數據。=》循環隊列會浪費一個數組的存儲空間
template < class T > class SeqQueue { protected : T
* element
; int front
, rear
; int maxSize
; public : SeqQueue ( int sz
= 10 ) { front
= rear
= 0 ; maxSize
= sz
; element
= new T
[ maxSize
] ; } ~ SeqQueue ( ) { delete [ ] element
; } bool EnQueue ( const T
& x
) { if ( isFull ( ) ) return false ; element
[ rear
] = x
; rear
= ( rear
+ 1 ) % maxSize
; return true ; } bool DeQueue ( T
& x
) { if ( isEmpty ( ) ) return false ; x
= element
[ front
] ; front
= ( front
+ 1 ) % maxSize
; return true ; } bool getFront ( T
& x
) { if ( isEmpty ( ) ) return false ; x
= element
[ front
] ; return true ; } void makeEmpty ( ) { front
= rear
= 0 ; } bool isEmpty ( ) const { return ( rear
== front
) ? true : false ; } bool isFull ( ) const { return ( ( rear
+ 1 ) % maxSize
== front
) ? true : false ; } int getSize ( ) const { return ( rear
- front
+ maxSize
) % maxSize
; } } ;
4、阻塞隊列
支持阻塞操作的隊列。具體來講,支持阻塞添加和阻塞移除。
阻塞添加: 當隊列滿的時候,隊列會阻塞插入插入的元素的線程,直到隊列不滿; 阻塞移除: 在隊列為空時,隊里會阻塞插入元素的線程,直到隊列不滿。
阻塞隊列常用于“生產者-消費者模型”,生產者是向隊列添加元素的線程;消費者是從隊列取元素的線程。
5、并發隊列
并發隊列就是隊列的操作多線程安全。 實現:基于數組的循環隊列,利用CAS原子操作,可以實現非常高效的并發隊列
總結
以上是生活随笔 為你收集整理的五、队列(Queue) 的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網站內容還不錯,歡迎將生活随笔 推薦給好友。