今天講優先佇列(簡單易懂)
首先講什麼是佇列:佇列與棧往往會放到一起去講,棧是一種先進後出(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...