python數據結構與算法-16_優先級隊列

優先級隊列

你可能比較奇怪,隊列不是早就講了嘛。這里之所以放到這里講優先級隊列,是因為雖然名字有隊列,
但其實是使用堆來實現的。上一章講完了堆,這一章我們就趁熱打鐵來實現一個優先級隊列。

實現優先級隊列

優先級隊列(Priority Queue) 顧名思義,就是入隊的時候可以給一個優先級,通常是個數字或者時間戳等,
當出隊的時候我們希望按照給定的優先級出隊,我們按照 TDD(測試驅動開發) 的方式先來寫測試代碼:

def test_priority_queue():size = 5pq = PriorityQueue(size)pq.push(5, 'purple')    # priority, valuepq.push(0, 'white')pq.push(3, 'orange')pq.push(1, 'black')res = []while not pq.is_empty():res.append(pq.pop())assert res == ['purple', 'orange', 'black', 'white']

上邊就是期望的行為,寫完測試代碼后我們來編寫優先級隊列的代碼,按照出隊的時候最大優先級先出的順序:

class PriorityQueue(object):def __init__(self, maxsize):self.maxsize = maxsizeself._maxheap = MaxHeap(maxsize)def push(self, priority, value):# 注意這里把這個 tuple push 進去,python 比較 tuple 從第一個開始比較# 這樣就很巧妙地實現了按照優先級排序entry = (priority, value)    # 入隊的時候會根據 priority 維持堆的特性self._maxheap.add(entry)def pop(self, with_priority=False):entry = self._maxheap.extract()if with_priority:return entryelse:return entry[1]def is_empty(self):return len(self._maxheap) == 0

源碼

# -*- coding:utf-8 -*-# 第二章拷貝的 Array 代碼class Array(object):def __init__(self, size=32):self._size = sizeself._items = [None] * sizedef __getitem__(self, index):return self._items[index]def __setitem__(self, index, value):self._items[index] = valuedef __len__(self):return self._sizedef clear(self, value=None):for i in range(len(self._items)):self._items[i] = valuedef __iter__(self):for item in self._items:yield item#####################################################
# heap 實現
#####################################################class MaxHeap(object):"""Heaps:完全二叉樹,最大堆的非葉子節點的值都比孩子大,最小堆的非葉子結點的值都比孩子小Heap包含兩個屬性,order property 和 shape property(a complete binary tree),在插入一個新節點的時候,始終要保持這兩個屬性插入操作:保持堆屬性和完全二叉樹屬性, sift-up 操作維持堆屬性extract操作:只獲取根節點數據,并把樹最底層最右節點copy到根節點后,sift-down操作維持堆屬性用數組實現heap,從根節點開始,從上往下從左到右給每個節點編號,則根據完全二叉樹的性質,給定一個節點i, 其父親和孩子節點的編號分別是:parent = (i-1) // 2left = 2 * i + 1rgiht = 2 * i + 2使用數組實現堆一方面效率更高,節省樹節點的內存占用,一方面還可以避免復雜的指針操作,減少調試難度。"""def __init__(self, maxsize=None):self.maxsize = maxsizeself._elements = Array(maxsize)self._count = 0def __len__(self):return self._countdef add(self, value):if self._count >= self.maxsize:raise Exception('full')self._elements[self._count] = valueself._count += 1self._siftup(self._count-1)  # 維持堆的特性def _siftup(self, ndx):if ndx > 0:parent = int((ndx-1)/2)if self._elements[ndx] > self._elements[parent]:    # 如果插入的值大于 parent,一直交換self._elements[ndx], self._elements[parent] = self._elements[parent], self._elements[ndx]self._siftup(parent)    # 遞歸def extract(self):if self._count <= 0:raise Exception('empty')value = self._elements[0]    # 保存 root 值self._count -= 1self._elements[0] = self._elements[self._count]    # 最右下的節點放到root后siftDownself._siftdown(0)    # 維持堆特性return valuedef _siftdown(self, ndx):left = 2 * ndx + 1right = 2 * ndx + 2# determine which node contains the larger valuelargest = ndxif (left < self._count and     # 有左孩子self._elements[left] >= self._elements[largest] andself._elements[left] >= self._elements[right]):  # 原書這個地方沒寫實際上找的未必是largestlargest = leftelif right < self._count and self._elements[right] >= self._elements[largest]:largest = rightif largest != ndx:self._elements[ndx], self._elements[largest] = self._elements[largest], self._elements[ndx]self._siftdown(largest)class PriorityQueue(object):def __init__(self, maxsize):self.maxsize = maxsizeself._maxheap = MaxHeap(maxsize)def push(self, priority, value):entry = (priority, value)    # 注意這里把這個 tuple push進去,python 比較 tuple 從第一個開始比較self._maxheap.add(entry)def pop(self, with_priority=False):entry = self._maxheap.extract()if with_priority:return entryelse:return entry[1]def is_empty(self):return len(self._maxheap) == 0def test_priority_queue():size = 5pq = PriorityQueue(size)pq.push(5, 'purple')pq.push(0, 'white')pq.push(3, 'orange')pq.push(1, 'black')res = []while not pq.is_empty():res.append(pq.pop())assert res == ['purple', 'orange', 'black', 'white']def test_buildin_PriorityQueue():  # python3"""測試內置的 PriorityQueuehttps://pythonguides.com/priority-queue-in-python/"""from queue import PriorityQueueq = PriorityQueue()q.put((10, 'Red balls'))q.put((8, 'Pink balls'))q.put((5, 'White balls'))q.put((4, 'Green balls'))while not q.empty():item = q.get()print(item)def test_buildin_heapq_as_PriorityQueue():"""測試使用 heapq 實現優先級隊列,保存一個 tuple 比較元素(tuple第一個元素是優先級)"""import heapqs_roll = []heapq.heappush(s_roll, (4, "Tom"))heapq.heappush(s_roll, (1, "Aruhi"))heapq.heappush(s_roll, (3, "Dyson"))heapq.heappush(s_roll, (2, "Bob"))while s_roll:deque_r = heapq.heappop(s_roll)print(deque_r)# python3 沒有了 __cmp__ 魔法函數 https://stackoverflow.com/questions/8276983/why-cant-i-use-the-method-cmp-in-python-3-as-for-python-2
class Item:def __init__(self, key, weight):self.key, self.weight = key, weightdef __lt__(self, other): # 看其來 heapq 實現只用了 小于 比較,這里定義了就可以 push 一個 item 類return self.weight < other.weightdef __eq__(self, other):return self.weight == other.weightdef __str__(self):return '{}:{}'.format(self.key,self.weight)def test_heap_item():"""測試使用 Item 類實現優先級隊列,因為 heapq 內置使用的是小于運算法,重寫魔術 < 比較方法即可實現"""import heapqpq = []heapq.heappush(pq, Item('c', 3))heapq.heappush(pq, Item('a', 1))heapq.heappush(pq, Item('b', 2))while pq:print(heapq.heappop(pq))

練習題

  • 請你實現按照小優先級先出隊的順序的優先級隊列

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/163905.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/163905.shtml
英文地址,請注明出處:http://en.pswp.cn/news/163905.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

UWA報告使用技巧小視頻,你get了么?(第十一彈)

隨著玩家對手游渲染品質的要求日益趨上&#xff0c;60幀、各種花式后處理導致發熱、耗電等問題日趨明顯。本期UWA報告使用技巧將分享關于GPU優化的專題姊妹篇。 《GPU性能優化篇》 UWA專注于手游GPU性能的優化&#xff0c;以確保您的游戲體驗得以最佳展現。基于最新發布的GOT …

141.【Git版本控制】

Git-深入挖掘 (一)、Git分布式版本控制工具1.目標2.概述(1).開發中的實際常見(2).版本控制器的方式(3).SVN (集中版本控制器)(4).Git (分布版本控制器)(5).Git工作流程圖 (二)、Git安裝與常用命令1.Git環境配置(1).安裝Git的操作(2).Git的配置操作(3).為常用的指令配置別名 (可…

輕松解決rpm軟件包的依賴問題 yum download ,rpm和deb不同系列

centos rpm系列的 為它往往有很多依賴項目。比如&#xff0c;我們來查看一下net-tools的依賴項有哪些&#xff1a; yum deplist net-tools 推薦使用以下幾種方法&#xff1a; 1.repotrack 我這里也以上期講到的Mariadb為例演示&#xff0c;以下操作需要在有網絡的環境下進…

國內企業出海首選的免費開源訂單管理系統(OMS)解決方案

用開源智造Odoo訂單管理系統 (OMS) 解決方案實現"訂單到收款"流程自動化 開源智造Odoo 訂單管理軟件功能消除了手動操作瓶頸&#xff0c;可防止出錯&#xff0c;還建立了從銷售報價到訂單履行的順暢工作流來確保及時開票和付款&#xff0c;從而幫助您理順訂單處理過程…

Python將多個視頻幀組合成.mp4視頻

已經有很多文章描述了如何將視頻拆分成視頻幀&#xff0c;例如&#xff1a;https://blog.csdn.net/WYKB_Mr_Q/article/details/124929081 那我們如何將很多視頻幀重新組合成視頻呢&#xff1f; 這里我們主要用到了 OpenCV 庫中的 VideoWriter 類。 OpenCV種的 cv2.VideoWrit…

jdbc批量插入或更新數據

mybatis可以批量插入或更新數據&#xff0c;不過mybatis底層也是基于jdbc來實現的&#xff0c;如何使用jdbc批量操作數據&#xff1f;本文給出demo。 /*** JDBC分批次批量插入* * throws IOException*/public static void testJDBCBatchInsertUser() throws IOException {Conne…

工作流引擎的架構設計主要考慮以下方面

工作流引擎的架構設計主要考慮以下方面&#xff0c;以馳騁工作流引擎為例來說明。 高度抽象和封裝&#xff1a;為了適應各種業務場景&#xff0c;工作流引擎應具備高度抽象和封裝的特性&#xff0c;以便統一處理各流程。靈活配置&#xff1a;工作流引擎應支持靈活的配置&#…

Linux之實現簡易的shell

1.打印提示符并獲取命令行 我們在使用shell的時候&#xff0c;發現我們在輸入命令是&#xff0c;前面會有&#xff1a;有用戶名&#xff0c;版本&#xff0c;當前路徑等信息&#xff0c;這里我們可以用環境變量去獲取: 1 #include <stdio.h>2 #include <stdlib.h>…

python如何快速查找到想要的文檔

字多不看版&#xff0c;直接體驗 待補充 演示代碼 # -*- coding:UTF-8 -*-# region 導入必要的依賴包 import os import subprocess from enum import Enum模塊名 pyperclip try:import pyperclip # 需要安裝 pyperclip 模塊&#xff0c;以支持粘貼板操作 except ImportEr…

PTA-成績轉換

本題要求編寫程序將一個百分制成績轉換為五分制成績。轉換規則&#xff1a; 大于等于90分為A&#xff1b;小于90且大于等于80為B&#xff1b;小于80且大于等于70為C&#xff1b;小于70且大于等于60為D&#xff1b;小于60為E。 輸入格式: 輸入在一行中給出一個整數的百分制成…

羊大師教你如何科學控制體重,輕松瘦下來

羊大師教你如何科學控制體重&#xff0c;輕松瘦下來 我們都知道&#xff0c;控制體重對于保持健康和美麗至關重要。然而&#xff0c;許多人在減肥的道路上走得波折重重&#xff0c;常常陷入挫敗和不知所措的境地。那么&#xff0c;如何科學控制體重&#xff0c;輕松瘦下來呢&a…

項目經理只需要有PMP證書就行?

就目前而言&#xff0c;大部分人對于項目經理的認識還停留在&#xff1a;有項目管理經驗&#xff0c;有對應的工作年限&#xff0c;有PMP證書。所以絕大多數人都認為只要報考了PMP項目管理&#xff0c;取得PMP證書&#xff0c;即可加入項目經理的圈子&#xff0c;薪資翻倍。 但…

協同過濾與矩陣分解講解(PPT)

總覽 協同過濾算法&#xff0c;就是一種完全依賴用戶和物品之間行為關系的推薦算法。 從字面理解&#xff0c;協同大家的反饋、評價和意見一起對海量的信息進行過濾&#xff0c;從中篩選出用戶可能感興趣的信息。 知識概括 從這幾個方面進行分析。 一、基于用戶的協同過濾 顯示…

6個PPT素材網站,讓你快速做出好看的PPT

找PPT模板一定要收藏好這6個網站&#xff0c;能讓你快速做出好看的PPT&#xff0c;重點十可以免費下載&#xff0c;趕緊收藏&#xff01; 1、菜鳥圖庫 https://www.sucai999.com/search/ppt/0_0_0_1.html?vNTYwNDUx 菜鳥圖庫網有非常豐富的免費素材&#xff0c;像設計類、辦公…

力扣labuladong——一刷day48

提示&#xff1a;文章寫完后&#xff0c;目錄可以自動生成&#xff0c;如何生成可參考右邊的幫助文檔 文章目錄 前言一、力扣1602. 找到二叉樹中最近的右側節點二、力扣437. 路徑總和 III三、力扣560. 和為 K 的子數組 前言 二叉樹的遞歸分為「遍歷」和「分解問題」兩種思維模式…

第7章-使用統計方法進行變量有效性測試-7.4.2-多元線性回歸

目錄 多元線性回歸模型 總體回歸函數 樣本回歸函數 線性回歸模型的假定 普通最小二乘法&#xff08;Ordinary Least Squares&#xff0c;OLS&#xff09; 擬合優度指標 F檢驗 回歸系數的t檢驗 Python中構建多元線性回歸模型 數據理解 數據讀取 數據清洗 相關分析 …

想考教師編制專業不對口怎么辦?

很多人在想要步入教師行業時&#xff0c;會遇到一個問題&#xff1a;專業不對口。這種情況可能會讓你感到困惑和沮喪&#xff0c;但不要氣餒&#xff0c;因為有很多方法可以讓你實現自己的夢想。 可以通過提高自己的教育水平和能力來彌補專業不對口的缺陷。你可以通過參加教師資…

品牌小紅書koc投放策略分享,純干貨!

作為中國具有影響力的時尚美妝社交平臺&#xff0c;小紅書與其充滿活力的用戶群體成為品牌尋找優質KOC合作的理想平臺。本文伯樂網絡傳媒將探討品牌如何利用小紅書的KOC投放策略&#xff0c;實現更廣泛的市場覆蓋和更有效的品牌營銷。 一、明確目標受眾與KOC合作需求 在開始策…

containerd Snapshots功能解析

containerd Snapshots功能解析 snapshot是containerd的一個核心功能&#xff0c;用于創建和管理容器的文件系統。 本篇containerd版本為v1.7.9。 本文以 ctr i pull命令為例&#xff0c;分析containerd的snapshot “創建” 相關的功能。 ctr命令 ctr image相關命令的實現在cmd…

《人件》讀書筆記

文章目錄 一、書名和作者二、書籍概覽2.1 主要論點和結構2.2 目標讀者和應用場景 三、核心觀點與主題3.1 管理團隊主題3.2 改善工作環境主題3.3 正確的人主題3.4 團隊項目管理主題 四、亮點與啟發4.1 最有影響的觀點4.2 對個人專業發展的啟示 五、批評與局限性5.1 可能存在爭議…