優先佇列
佇列是乙個操作受限的線性表,資料只能在一端進入,另一端出來,具有先進先出的性質。有時在佇列中需要處理優先順序的情況,即後面進入的資料需要提前出來,這裡就需要優先佇列。優先佇列是至少能夠提供插入和刪除最小值這兩種操作的資料結構。對應於佇列的操作,插入相當於入隊,刪除最小相當於出隊。
鍊錶,二叉查詢樹,都可以提供插入和刪除最小這兩種操作。對於鍊錶的實現,插入需要o(1),刪除最小需要遍歷鍊錶,故需要o(n)。對於二叉查詢樹,這兩種操作都需要o(logn);而且隨著不停的刪除最小的操作,二叉查詢樹會變得非常不平衡;同時使用二叉查詢樹有些浪費,因此很多操作根本不需要。一種較好的實現優先佇列的方式是二叉堆(下面簡稱堆)。
堆
堆實質上是滿足如下性質的完全二叉樹:樹中任一非葉結點的關鍵字均不大於(或不小於)其左右孩子(若存在)結點的關鍵字。首先堆是完全二叉樹(只有最下面的兩層結點度能夠小於2,並且最下面一層的結點都集中在該層最左邊的若干位置的二叉樹),其次任意節點的左右孩子(若有)值都不小於其父親,這是小根堆,即最小的永遠在上面。相反的是大根堆,即大的在上面。
因為完全二叉樹有很好的規律,因此可以只用資料來儲存資料而不需要鍊錶。如下圖:
如圖儲存在陣列中的資料a~j,對於任意位置i,其左兒子在陣列中位置為2i,其右兒子在陣列中位置為2i+1,其父親位置在floor(i/2)。
堆的插入:插入堆,那麼堆中元素將加一,會在最後乙個葉子後新增乙個葉子,如上圖中的j後面。新增了乙個葉子後,需要按照大小比較將這個值放到特定的位置,直到滿足堆條件,這是個上濾過程。
堆的刪除最小:刪除堆中最小的乙個,對於小根堆來說就是刪除根,刪除根後,需要將下面的元素按照大小規則往上移,直到刪除最後乙個葉子,這是個下濾過程。
建堆的時間複雜度為o(n),刪除堆最小值的時間複雜度為o(logn),n為節點數。
定義乙個堆結構並實現資料插入和刪除最小值操作:
#define max 20
struct
queue
;//insert a data to queue;
void insert(queue &q, int x)
else
break; //
} q.size++;
}//delete the minimum data in the queue
void deletemin(queue &q)
else
} q.data[tmp] = q.data[q.size-1];
q.data[q.size-1] = 0;
q.size--;
}int main()
參考:
優先佇列及最小堆最大堆
priority queue(heaps)–優先佇列(堆)
stl中的優先佇列:priority_queue
priority_queue為stl中實現的優先佇列結構,輸入存入佇列會自動按照大根堆的性質儲存。它的模板宣告帶有三個引數:
priority_queue
type 為資料型別,container 為儲存資料的容器,functional 為元素比較方式。container 必須是用陣列實現的容器,比如 vector, deque 但不能用 list。stl裡面預設用的是 vector,比較方式預設用 operator< , 所以如果你把後面倆個引數預設的話,優先佇列就是大頂堆,隊頭元素最大。
priority_queue,greater>q3
;//定義小的先出隊
常用的函式:
push()
//插入乙個數;
pop()
//刪除最小(大)的那個數;
//front() //返回隊首元素;
//back() //返回隊尾元素;
top()
//返回隊頂元素,沒有上面兩個,queue才有
empty()
//佇列是否為空
size()
//佇列中元素個數
priority_queue定義在標頭檔案queue中,在此檔案中還有一種資料型別queue,即單向佇列,基本操作也是上面的幾個函式,與雙向佇列deque略有差別。
基本定義:queueq;
int main()
需要注意的是:優先佇列priority_queue是不支援迭代器的運算的,讀取元素只能在佇列首部讀取(top), queue也是一樣的不支援,因此不能對queue進行排序,只能讀取隊首和隊尾的資料(front,back()),同樣的stack也是一樣不能使用迭代器,只能讀取棧頂的資料。
對於自己定義的資料型別作為佇列引數,用法參考:priority_queue的用法
優先佇列《堆》
1.模型 兩個基本操作 insert等價enqueue deletemin刪除最小者 dequeue 2.簡單的實現 1 簡單鍊錶 遍歷刪除min或者排序刪除min 2 使用二叉查詢樹。反覆除去min會使得樹不平衡,並且bst還支援許多不需要的操作。3.二叉堆 優先佇列的實現普遍使用二叉堆,堆有兩個...
優先佇列 堆
印表機列印作業一般是放在佇列中的。如果按照先來先列印的順序,有乙個100頁的列印任務,那麼會讓後面短小的任務等待很長時間。更合理的做法也許是最後處理最耗時的列印任務,不管它是不是最後提交上來的。在多使用者作業系統中,作業系統讓哪個程式使用cpu,是需要決定從佇列裡面選擇的。一般做法是從隊頭獲得程式,...
堆 優先佇列
面試的時候被問到了heapsort,發現自己對資料結構這塊的理解實在不夠,最近打算推翻重新來學一遍。這裡先簡單地說一下自己對堆的理解。堆的特質 1.平衡二叉樹 保證了操作時間複雜度為logn 2.以最小堆為例,對任意結點,其父節點均小於子節點。這樣幾乎各種操作都是在縱向上 深度 進行的。由於在堆這個...