日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

五、队列(Queue)

發布時間:2025/3/19 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 五、队列(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;elsereturn false; } bool isQueueFull(Queue &Q) {if((Q.rear+1)%MAXSIZE == Q.head)return true;elsereturn 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//定義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; //設置元素個數為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++; //元素個數加1 } 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;elsecout << "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;elsecout << endl; } bool QUEUE::isempty() {return front->next == tail; } int main(int argc, char const *argv[]) {QUEUE que; /* *do somthing here */ 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)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。