佇列與優先順序佇列詳解!

2021-09-26 11:00:46 字數 3930 閱讀 5559

今天講優先佇列(簡單易懂)

首先講什麼是佇列:佇列與棧往往會放到一起去講,棧是一種先進後出(filo)的資料結構,而佇列,則是一種先進先出的資料結構(fifo)那麼什麼是先進先出呢?就像是你去食堂排隊打飯,你先到了,就先排上隊伍,然後先打上飯,自然而然也就先離開隊伍去餐桌恰飯!

/我們這篇blog主要講應用,所以很多函式的實現原理就不多說了/

一、標頭檔案:

#include using namespace std;
無論是一般的佇列,還是啥啥啥的佇列,都是這個庫!

二、佇列的宣告:

queue 《資料型別》 佇列名;

比如:queue q;

queue q;

queue q;//node 是乙個結構體型別,很常用

三、佇列的操作

q.push(item);//入佇列,從隊尾入隊哦!

q.top();//返回隊首元素,但是不會刪除哦!q.front();也可以

q.pop();//刪除隊首元素,注意和上面的做對比哦!

q.back();//返回隊尾元素

q.size();//返回元素個數

q.empty();//bool變數,如果隊列為空則返回true

佇列的基本操作就在上面了,值得注意的是:

佇列只允許在隊首出隊,隊尾入隊(可以用打飯去理解)

四、好吧,鑑於很多朋友學的是c語言實現資料結構,又不會stl,那我就寫乙個佇列

其實手寫佇列也是有好處的!!!就和棧一樣,如果用stl,很容易出現溢位哦!

但是手寫,即可解決掉這個問題!

class queue;

void queue::init_queue(queue q)//初始化的時候全設為-1,當有入隊和出隊的時候,head++(出隊),tail++(入隊)

bool queue::empty(queue q)//顯然,當head和tail再次相遇的時候,即是隊空的時候

bool push(queue q, int e)

void queue::pop(queue q)

哎呀媽,好久沒有手寫佇列了,要是有用錯類與物件的地方,還請多提出,很抱歉啊,還是沒能擺脫c++去寫這個佇列的資料結構,希望大家在學習資料結構的時候,多自己去實現,而不是光去使用!

五、總結佇列

佇列的好處:可以很快做到先進先出的次序,能在o(1)的複雜度內去進行添入和刪除元素

佇列的壞處:不知道大家有沒有發現,佇列的入隊和出隊操作都是把下標++,這樣就會造成前面使用過的記憶體空間,一旦元素被刪除,那麼該空間將永遠不再被使用!!這樣將是對空間的極大浪費!於是我們有了迴圈佇列!關於迴圈佇列,很多資料結構的書上都有詳細的**,我也就不再贅述。

只是其實用迴圈佇列也有相應的不足:迴圈佇列要事先申請好空間,整個過程都不能釋放,而且要有固定的長度,如果長度事先無法估計,這種方式顯然不夠靈活;所以就引入了鏈式儲存佇列,其實就是線性表的單鏈表,只是它只能對尾進,隊頭出。並且規定隊頭指標指向鏈佇列的頭結點,對尾指標指向終端節點,當隊列為空時,head和tail都指向頭結點。

六、優先順序佇列

優先佇列具有根據一定的優先順序順序自動排序的功能

優先佇列,顧名思義,就是讓優先順序高的先出列,它是佇列與排序的完美結合!不僅可以儲存資料,還可以按照一定的優先順序進行排序,對每一次的push()和pop()操作,優先佇列都會自己動態調整,把優先順序更高的元素放在前面,維護了乙個全域性的有序性!!

在stl中,優先佇列是運用二叉堆來實現的,每次push()和pop()操作,複雜度都是o(logn)。而運用優先佇列排序的複雜度是o(nlogn)還是很優的!

七、優先佇列的宣告:

priority_queue 《資料型別》 q;
比如:

priority_queue q;

priority_queue q;

priority_queue q;//老樣子,node是一種結構體型別

然後講講優先佇列的模板:

priority_queue ,less> q;

//第乙個int:優先佇列裡儲存的資料型別

//第二個vector:優先佇列的儲存工具是向量(不重要,曉得就可以了)

//第三個less:指的是該佇列是降序排列(可以不寫哦,因為優先佇列預設就是降序的)

//有降序就有公升序

priority_queue ,greater> q;

//後面兩個》不要寫到一起,要空格隔開,不然就和右移運算重複了

//有公升序、降序,就有自定義順序!!

八、優先佇列自定義優先順序的方法

struct node

}

不知道大家看到這裡會不會想到sort函式裡的compare函式,大家看看compare函式會咋寫來實現這個功能

bool cmp(node n1, node n2)
大家可以看到,在compare函式裡,我們預設寫在前面的n1是排在前面的,而n2就排在n1的後頭。

那麼我們模擬一下,過載運算子函式裡的n預設是排在前面的,而結構體裡的則是預設排在n後面的,不知道這樣講大家能否感知到我的意思。

題目分析:

這個題,病人有三個屬性:來的順序(id),想找哪位醫生(a),優先順序(b)

這裡如果用sort裡那種compare函式的寫法,應該如下:

bool cmp(node n1, node n2)
那如果是過載運算子呢?

struct node

};

#include #include #include using namespace std;

struct node

};int main()

else

else

cout << "empty" << endl;

}} }

return 0;

}

總結一下優先順序佇列的解題方法:

①:優先順序佇列往往是面向乙個類(結構體)的物件(變數)去設定優先順序,所以我們一定要熟練掌握在結構體內過載『<』運算子的方法

②:對乙個類去宣告優先佇列的方法是priority_queue q;這裡我們入佇列的一定是乙個結構體變數!!!於是我們在入佇列操作前,一定要先宣告乙個結構體變數:node n;然後對應地去給這個結構體變數賦值,賦值完畢後再入佇列操作:q.push(n);

學會了方法之後再看一道入門題:

hduoj 1509

題目分析:

這個題說接收指令,如果是put就輸入指令,指令包括一下屬性:指令名稱,指令資訊,指令優先順序,這裡有個地方比較坑,他說優先順序數值低的指令優先順序高……

還是先用大家熟悉的sort裡面的compare函式寫一下:

bool cmp(node n1, node n2)
那我相信大家一定也會寫過載運算子的函式了吧

struct node

};

#include #include #include #include using namespace std;

const int maxn = 60005;

struct node

};char command[maxn];//不能用 string 因為string不能承受60005這麼大,會溢位

int main()elseelse

cout << "empty queue!" << endl;

} }return 0;

}

順序佇列與優先佇列的基礎知識就講到這裡!運用好優先佇列還是可以解很多題的!

佇列 優先順序佇列

優先順序佇列的隊尾是不需要改變的,永遠在低下標處。當佇列增加資料時,隊頭的位置就是資料項的大小減去1.public class priorityq 插入 public void insert long item else quearray j 1 item nitem 刪除 public long ...

優先順序佇列

分為最小優先順序佇列和最大優先順序佇列。優先順序佇列是一種用來維護一組元素構成的集合s的資料結構,這一組元素都有乙個關鍵字key,乙個最大優先順序佇列支援的操作 insert s,x 把x插入到集合s中 maxmum s 返回s中最大元素 extra max s 去掉s中最大關鍵字並返回該最大關鍵子...

優先順序佇列

1 include stdafx.h 2 include3 4 using namespace std 5 6 define max heap len 107 int heap max heap len 8 int heap size 0 the number of elements in heap...