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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > python >内容正文

python

堆排序不稳定的例子_【译】Python中的堆排序

發(fā)布時間:2025/3/11 python 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 堆排序不稳定的例子_【译】Python中的堆排序 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

作者:Olivera Popovi?

翻譯:老齊

介紹

堆排序是高效排序算法的另一個例子,它的主要優(yōu)點(diǎn)是,無論輸入數(shù)據(jù)如何,它的最壞情況運(yùn)行時間都是O(n*logn)。

顧名思義,堆排序在很大程度上依賴于堆數(shù)據(jù)結(jié)構(gòu)——優(yōu)先級隊列的常見實(shí)現(xiàn)。

毫無疑問,堆排序是一種簡單的排序算法,而且與其他簡單實(shí)現(xiàn)相比,堆排序是更有效,也很常見。

堆排序

堆排序的工作原理是從堆逐個“移除”元素并將它們添加到已排序的數(shù)組里,在進(jìn)一步解釋和重新訪問堆數(shù)據(jù)結(jié)構(gòu)之前,我們應(yīng)該了解堆排序本身的一些屬性。

它是一種原地算法(譯者注:in-place algorithm,多數(shù)翻譯為“原地算法”,少數(shù)也翻譯為“就地算法”。這種算法是使用小的、固定數(shù)量的額外內(nèi)存空間來轉(zhuǎn)換資料的算法。),意味著它需要恒定數(shù)量的內(nèi)存,即所需內(nèi)存不取決于初始數(shù)組本身的大小,而取決于存儲該數(shù)組所需的內(nèi)存。

例如,不需要原始數(shù)組的副本,也不需要遞歸和遞歸調(diào)用堆棧。最簡單的堆排序?qū)崿F(xiàn)通常使用第二個數(shù)組來存儲排序后的值。我們將使用這種方法,因為它在代碼中更直觀、更易于實(shí)現(xiàn),但它也是百分百的原地算法。

堆排序不穩(wěn)定,意思是相等的值,并不會在同樣的相對位次上。對于整數(shù)、字符串等這些基本類型,不會出現(xiàn)這類問題,但當(dāng)我們對復(fù)雜類型的對象排序時,可能會遇到。

例如,假設(shè)我們有一個自定義類Person帶有age和name屬性,在一個數(shù)組中幾個此類的實(shí)例對象,比如按順序出現(xiàn)19歲的名叫“Mike”的人和一個19歲的名叫“David”的人。

如果我們決定按年齡對這些人進(jìn)行排序,就不能在排序數(shù)組中保證“Mike”會出現(xiàn)在“David”之前,即使他們在初始數(shù)組中是按這個順序出現(xiàn)的。“Mike”有可能出現(xiàn)在“David”之前,但不能保證百分之百如此。

堆數(shù)據(jù)結(jié)構(gòu)

堆是計算機(jī)科學(xué)中最流行和最常用的一種數(shù)據(jù)結(jié)構(gòu)——更不用說在軟件工程面試中非常流行了。

我們將討論跟蹤最小元素(最小堆)的堆,但它們也可以很容易地實(shí)現(xiàn)對最大元素(最大堆)的跟蹤。

簡單地說,最小堆是一種基于樹的數(shù)據(jù)結(jié)構(gòu),其中每個節(jié)點(diǎn)比其所有子節(jié)點(diǎn)都小。通常使用二叉樹。堆有三個基本操作——delete_minimum()、get_minimum()和add()。

每次,你只能刪除堆中的第一個元素,然后對其進(jìn)行“重新排序”。在添加或刪除元素后,堆對自己會“重新排序”,以便最小的元素始終處于第一個位置。

注意:這絕不意味著堆是排序的數(shù)組。每個節(jié)點(diǎn)都小于其子節(jié)點(diǎn)這一事實(shí)不足以保證整個堆是按升序排列的。

我們來看一個關(guān)于堆的例子:

正如我們看到的,上面的例子確實(shí)符合堆的描述,但是沒有排序。我們不會詳細(xì)討論堆實(shí)現(xiàn),因為這不是本文的重點(diǎn)。當(dāng)在堆排序中使用堆數(shù)據(jù)結(jié)構(gòu)時,我們所利用的堆數(shù)據(jù)結(jié)構(gòu)的關(guān)鍵優(yōu)勢是:下一個最小的元素始終是堆中的第一個元素。

實(shí)現(xiàn)

數(shù)組排序

譯者注: 作者在本文中并沒有嚴(yán)格區(qū)分Python中的列表和數(shù)組,而是將列表看做了數(shù)組,這對于列表中的元素是同一種類型的元素而言,無可厚非。對于排序,只有是同一種類型的元素,才有意義。

Python提供了創(chuàng)建和使用堆的方法,所以我們不必自己單獨(dú)為了實(shí)現(xiàn)它們?nèi)懘a了:

  • heappush(list, item):向堆中添加一個元素,然后對其重新排序,使其保持堆狀態(tài)。可用于空列表。
  • heappop(list):刪除第一個(最小的)元素并返回該元素。此操作之后,堆仍然是一個堆,因此我們不必調(diào)用heapify()。
  • heapify(list):將給定的列表變成一個堆。

現(xiàn)在我們知道了這些,堆排序的實(shí)現(xiàn)就相當(dāng)簡單了:

from heapq import heappop, heappushdef heap_sort(array):heap = []for element in array:heappush(heap, element)ordered = []# While we have elements left in the heapwhile heap:ordered.append(heappop(heap))return orderedarray = [13, 21, 15, 5, 26, 4, 17, 18, 24, 2] print(heap_sort(array))

輸出

[2, 4, 5, 13, 15, 17, 18, 21, 24, 26]

如我們所見,堆數(shù)據(jù)結(jié)構(gòu)的繁重工作已經(jīng)完成,我們所要做的只是添加所需的所有元素并逐個刪除它們。它就像一臺硬幣計數(shù)機(jī),根據(jù)輸入的硬幣的價值對它們進(jìn)行分類,然后我們可以取出它們。

自定義對象排序

當(dāng)使用自定義類時,事情會變得更加復(fù)雜。通常,為了使用我們的排序算法,建議不要重寫類中的比較運(yùn)算符,而是建議重寫該算法,以便使用lambda函數(shù)比較。

但是,由于我們的實(shí)現(xiàn)依賴于內(nèi)置堆方法,因此不能在這里這樣做。

Python確實(shí)提供了以下方法:

  • heapq.nlargest(*n*, *iterable*, *key=None*):返回一個列表,其中包含由iterable定義的數(shù)據(jù)集中的n個最大元素。
  • heapq.nsmallest(*n*, *iterable*, *key=None*):返回一個列表,其中包含由iterable定義的數(shù)據(jù)集中的n個最小元素。

我們可以使用它來簡單地獲取n = len(array)最大/最小元素,但是方法本身不使用堆排序,本質(zhì)上等同于只調(diào)用sorted()方法。

我們留給自定義類的唯一解決方案是實(shí)際重寫比較運(yùn)算符。遺憾的是,這使我們局限于對每個類只能進(jìn)行一種比較。在我們的示例中,我們被局限于按年份對Movie對象進(jìn)行排序。

但是,它確實(shí)讓我們演示了在自定義類上使用堆排序。我們來定義Movie類:

from heapq import heappop, heappushclass Movie:def __init__(self, title, year):self.title = titleself.year = yeardef __str__(self):return str.format("Title: {}, Year: {}", self.title, self.year)def __lt__(self, other):return self.year < other.yeardef __gt__(self, other):return other.__lt__(self)def __eq__(self, other):return self.year == other.yeardef __ne__(self, other):return not self.__eq__(other)

現(xiàn)在,讓我們稍微修改一下heap_sort()函數(shù):

def heap_sort(array):heap = []for element in array:heappush(heap, element)ordered = []while heap:ordered.append(heappop(heap))return ordered

最后,讓我們實(shí)例化一些電影,將它們放入一個數(shù)組中,然后對它們進(jìn)行排序:

movie1 = Movie("Citizen Kane", 1941) movie2 = Movie("Back to the Future", 1985) movie3 = Movie("Forrest Gump", 1994) movie4 = Movie("The Silence of the Lambs", 1991); movie5 = Movie("Gia", 1998)array = [movie1, movie2, movie3, movie4, movie5]for movie in heap_sort(array):print(movie)

輸出:

Title: Citizen Kane, Year: 1941 Title: Back to the Future, Year: 1985 Title: The Silence of the Lambs, Year: 1991 Title: Forrest Gump, Year: 1994 Title: Gia, Year: 1998

與其他排序算法的比較

堆排序被廣泛使用,主要原因是它的可靠性,盡管它經(jīng)常被運(yùn)行良好的“快速排序”法所超越(譯者注: 本文的微信公眾號“老齊教室”以系列文章,介紹各種排序算法,并且用Python語言實(shí)現(xiàn),敬請關(guān)注)。

堆排序的主要優(yōu)點(diǎn)是時間復(fù)雜度上的O(n*logn)上限以及安全性。Linux內(nèi)核開發(fā)人員給出了使用堆排序而不是快速排序的以下理由:

堆排序的平均排序時間和最壞排序時間均為O(n*logn),雖然qsort的平均速度快了20%,但不得不容忍O(n*n)的最壞可能情形和額外的內(nèi)存支出,這使它不太適合在操作系統(tǒng)內(nèi)核中使用。

此外,快速排序算法法在可預(yù)測的情況下表現(xiàn)不佳。并且,如果對內(nèi)部實(shí)現(xiàn)有足夠的了解,你可能會意識到它造成的安全風(fēng)險(主要是DDoS攻擊),因為不良的O(n^2)行為很容易被觸發(fā)。

經(jīng)常被用來與堆排序比較的另一種算法是歸并排序算法(譯者注: 本微信公眾號也會刊發(fā)相關(guān)文章給予介紹,敬請關(guān)注),它們具有相同的時間復(fù)雜度。

歸并排序的優(yōu)點(diǎn)是穩(wěn)定、可并行運(yùn)算,而堆排序兩者都做不到。

另一個注意事項是:即使復(fù)雜度相同,堆排序在大多數(shù)情況下也比歸并排序慢,因為堆排序具有較大的常數(shù)因子。

然而,堆排序比歸并排序更容易實(shí)現(xiàn),因此當(dāng)內(nèi)存比速度更重要時,它是首選。

結(jié)論

正如我們所看到的,堆排序不像其他高效的通用算法那么流行,但是它的可預(yù)測行為(而不是不穩(wěn)定的行為)使它成為一個很好的算法,適用于內(nèi)存和安全性比稍快的運(yùn)行速度更重要的場合。

實(shí)現(xiàn)和利用Python提供的內(nèi)置功能是非常直觀的,我們實(shí)際上要做的就是將元素放在一個堆中并取出它們,就像對待硬幣計數(shù)器一樣。

原文鏈接:https://stackabuse.com/heap-sort-in-python/

★ 關(guān)注微信公眾號:老齊教室。讀深度文章,得精湛技藝,享絢麗人生。

總結(jié)

以上是生活随笔為你收集整理的堆排序不稳定的例子_【译】Python中的堆排序的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 亚洲理论在线观看 | 国产一级一片免费播放放a 丁香六月色 | 欧美激情一区二区三级高清视频 | www.夜色| 国产美女极度色诱视频www | 秋霞欧美视频 | 自拍偷拍三级 | 91精品国产91久久久 | 欧美乱大交xxxxx | 欧美在线性爱视频 | 日韩毛片在线 | 老司机精品视频在线播放 | 97超碰碰 | 欧美αv| 97av免费视频 | 久久精品视频在线播放 | 激情影音 | 欧美福利片在线观看 | 操极品少妇 | 久久九九国产精品 | 超碰成人网 | 日韩av中字| 亚洲一卡二卡 | 一本在线免费视频 | 亚洲制服一区二区 | 波多野结衣一区二区三区中文字幕 | 欧美日韩三级在线观看 | 久久精品国产99国产 | 人妻少妇精品无码专区 | 日韩精品一区不卡 | 无码人妻久久一区二区三区不卡 | 欧美国产成人精品一区二区三区 | 欧美精品成人一区二区在线观看 | 熟女熟妇伦久久影院毛片一区二区 | 午夜视频免费在线观看 | 性巴克成人免费网站 | 九色自拍 | 丰满少妇在线观看网站 | 狠狠撸在线观看 | 韩国成人在线 | 亚洲福利视频网站 | 又白又嫩毛又多15p 超碰在线一区 | 97超视频| 葵司免费一区二区三区四区五区 | 日韩欧美一区二 | 女生张开腿让男生插 | 肮脏的交易在线观看 | 懂色av | 国产乱淫a∨片免费视频 | 国产乱淫av片免费 | 香蕉久久夜色精品 | 激烈的性高湖波多野结衣 | 污污网址在线观看 | 欧美精品h| 日韩视频在线观看免费 | 亚洲破处视频 | 97综合 | 日日狠狠 | 成人av番号网| 色哟哟网站入口 | 六月丁香综合 | 无码无遮挡又大又爽又黄的视频 | 成人久草 | 一本久道综合色婷婷五月 | 五月婷婷丁香网 | 久久泄欲网 | 色网站入口 | 性开放视频 | 日韩中文字幕免费在线观看 | 欧美综合网 | 无码人妻精品中文字幕 | 成人免费在线网址 | 国产一区精品在线观看 | 亚洲精品乱码久久久久久不卡 | 美女屁股眼视频免费 | 欧美肥老妇视频 | 巨茎大战刘亦菲 | 好色婷婷 | 91 色| 黄色av一区| 免费吸乳羞羞网站视频 | 黄色片在线免费观看视频 | 色噜噜日韩精品欧美一区二区 | 欧美韩国日本在线 | 欧美做爰全过程免费看 | 操欧美老女人 | 免费的a级片 | 黄色网免费观看 | 99re视频精品 | 美女91网站| 国产欧美一区二区三区鸳鸯浴 | 在线国产黄色 | 青青草久久 | 国产精品色 | 色综合天天综合网天天狠天天 | 色先锋资源网 | 日韩99| 91插插视频 | 欧美专区第二页 |