数据结构之队列queue
生活随笔
收集整理的這篇文章主要介紹了
数据结构之队列queue
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
C++數據結構之隊列queue
什么是隊列
隊列的基本特征
隊列是如何工作的
隊列的實現
隊列的應用
什么是隊列
與棧相反,隊列是一種先進先出(FIFO)的線性表,只允許在表的一端插入,在另一端刪除。允許插入的一端叫隊尾,允許刪除 的一端叫隊頭。比較典型的例子有日常生活中的排隊:銀行排序辦理業務、地鐵排隊上車(emmmm,這里假設所有人都遵守秩序)等,當然還有計算機系統的消息隊列,操作系統的作業調度(這兩者都可以看做是隊列,不過是隊列的高級應用:優先級隊列)等
隊列的基本特征
- 先進先出(FIFO) - 限制插入和刪除:隊尾(back)插入,隊頭(front)刪除隊列是如何工作的
如下圖所示:
front代表隊頭,back代表隊尾,初始狀態,front與back指向同一位置,當插入一個新元素a后,隊尾back向后移動一位,隊頭front不動,指向下一個位置,當在a的下一個位置插入元素b時,隊尾back繼續向后移動一位,直到滿隊列,此時back指向最后的位置。當刪除一個元素時,隊頭front向后移動一位,隊尾back不動。在這種隊列結構下,可以通過(front == back)來判斷隊列是否為空。
隊列的實現
隊列的實現主要有兩種方式:順序表和鏈表;隊列的操作主要有:取出隊頭元素(front())、 刪除隊頭元素(pop())、隊尾插入元素(push())、是否為空(Empty())、隊列元素數(size()) 、是否已滿(Full())順序表實現隊列
順序表的實現較為簡單,直接使用數據存儲數據即可,而front和back代表數組的下標(索引), 這樣做的缺點就是隊列的長度固定,同時由于每次刪除元素時,隊頭向后移動一位,當隊列中所有 元素被刪除時,此時front ==back,但是,此時繼續向隊列中插入元素時,就會出現數組越界的 情況。 如上所示,此時,front與back都以指向了最后位置,無法繼續在隊列中插入數,但是, front前面的空間仍舊是空的,沒有存儲內容,此時如果采用動態內存分配無疑會浪費內 存空間,因此,為了能夠充分利用已分配的數組空間,可以將數組想象為一個首尾相 接的環,循環存儲數據,稱之為循環隊列。 如上,將數組想象成環狀,初始時,front與back都指向起始位置,當有元素插入或者刪除時, 進行相應的移動,直到back的下一個位置為front時,隊列為滿。由于是環狀的,因此, front與back的代表的位置應該對隊列的長度取余后,才為數組的下標。同時,為了便于判斷 隊列為滿和隊列為空,在設置隊列長度時,應該為length+1,因為back始終指向隊尾元素的 下一個位置,所以,當隊列滿時,back應該指向隊列長度的下一個位置,從而,可以通過 (back+1)%(length+1) == front判斷隊列滿,通過back==front判斷隊列為空。代碼實現
//頭文件定義 template <typename T> class Queue { public:Queue(int max_size);virtual ~Queue();T & Front() const;void Pop();void Push(T &element);bool Empty() const;int size() const;bool Full() const; private:int front_;int back_;int size_;int max_size_;T *contain; //隊列指針};//代碼實現 #include "Queue.h" #include <iostream> #include <assert.h> ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// template <typename T> Queue<T>::Queue(int max_size) {front_ = back_ = 0;size_ = 0;max_size_ = max_size + 1;contain = new T[max_size_]; //比隊列長度多一個元素,用于輔助存放back_以及判斷滿 }template <typename T> Queue<T>::~Queue() {delete [] contain; }template <typename T> bool Queue<T>::Empty() const {return front_ == back_; //指向同一位置 }template <typename T> T & Queue<T>::Front() const {assert(!Empty()); //斷言不為空,為空則程序直接報出異常中止return contain[front_]; }template <typename T> bool Queue<T>::Full() const {return (back_ + 1) % max_size_ == front_; //由于是環狀所以對最大長度取余 }template <typename T> void Queue<T>::Pop() {front_ = (front_ + 1) % max_size_;size_--; }template <typename T> void Queue<T>::Push(T &element) {assert(!Full());contain[back_] = element;back_ = (back_ + 1) % max_size_;size_++; }template <typename T> int Queue<T>::size() const {return size_; }鏈表實現隊列
用鏈表來實現隊列更符合隊列的特征,不需要進行循環,刪除隊頭元素直接釋放隊頭元素 空間即可,插入隊尾時,直接新增空間即可添加,同時隊尾指針指向隊尾元素,不再指向 下一節點,如下圖所示。 與鏈表不同的是,鏈表有頭結點,而隊列不需要頭結點,空隊列時,隊頭指針與隊尾指針 都指向NULL,同時此時判斷隊列滿也沒有什么意義。因而用鏈表實現隊列的功能有取頭 節點(Front())、刪除頭節點(Pop())、插入新元素(Push())、是否為空(Empty()) 、隊列中元素個數(size())代碼實現
//頭文件定義 template <typename T> //節點 struct ListNode{T data;ListNode<T> *link; }; //鏈表類 template <typename T> class ListQueue { public:ListQueue();virtual ~ListQueue();T & front() const;void Pop();void Push(T &element);bool Empty() const;int size() const; private:int size_;ListNode<T> *front_;ListNode<T> *back_; };//cpp實現 #include "ListQueue.h" #include <iostream> #include <assert.h>////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// template <typename T> ListQueue<T>::ListQueue() {front_ = back_ = NULL;size_ = 0; }template <typename T> ListQueue<T>::~ListQueue() {while (!Empty()) {this->Pop();} }template <typename T> bool ListQueue<T>::Empty() const {return front_ == NULL; }template <typename T> T & ListQueue<T>::front() const{assert(!Empty());return front_->data; }template <typename T> void ListQueue<T>::Pop() {assert(!Empty());ListNode<T> *temp = front_;front_ = front_->link;delete temp;size_--; }template <typename T> void ListQueue<T>::Push(T &element) {ListNode<T> *new_node= new ListNode<T>;new_node->data = element;new_node->link = NULL;if (back_ == NULL) {front_ = back_ = new_node;} else {back_->link = new_node;back_ = back_->link;}size_++; }template <typename T> int ListQueue<T>::size() const {return size_; }隊列的應用
編程練習之隊列篇:舞伴問題
編程練習之隊列篇:游程編碼問題
編程練習之隊列篇:楊輝三角問題
編程練習之隊列篇:優先級隊列
未完待續
以上是我關于隊列的學習心得,如果有什么不對的地方,歡迎大家指出,一起交流討論
總結
以上是生活随笔為你收集整理的数据结构之队列queue的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 迅雷 linux 命令行 版本号,在Li
- 下一篇: 批处理事件查看器