版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
優(yōu)先級(jí)隊(duì)列、堆排序2016Fall《數(shù)據(jù)結(jié)構(gòu)》2022/12/191優(yōu)先級(jí)隊(duì)列
PriorityQueue2022/12/19與棧和隊(duì)列一樣:可以保存數(shù)據(jù)元素,訪問(wèn)、入、出不同之處:每個(gè)數(shù)據(jù)都附有優(yōu)先級(jí),任何時(shí)候訪問(wèn)、出對(duì)列的總是當(dāng)前隊(duì)列中最優(yōu)先的元素“有序”隊(duì)列!2022/12/19優(yōu)先級(jí)隊(duì)列classPrioQue:def__init__(self,elist=[]):self.elems=list(elist)
self.elems.sort(reverse=True)#由大到小排序 defis_empty(self):returnself.elems==[]defpeek(self):ifself.is_empty():raisePrioQueueError("intop")returnself.elems[-1]實(shí)現(xiàn)方式1:sortedlist2022/12/19
defdequeue(self):ifself.is_empty():raisePrioQueueError("inpop")returnself.elems.pop()
#元素由大到小排,直接pop
defenqueue(self,e):i=len(self.elems)-1whilei>=0:ifself.elems[i]<=e:i-=1else:
breakself.elems.insert(i+1,e)
#循環(huán)結(jié)束時(shí),遇到了第一個(gè)大于e的元素elems[i]
#入隊(duì)列的時(shí)間復(fù)雜度:O(n)2022/12/19
入隊(duì)列時(shí)保持有序,出隊(duì)列直接pop;入隊(duì)列:O(n)出對(duì)列:O(1)入隊(duì)列時(shí)不處理,出隊(duì)列時(shí)搜索最優(yōu)先:入隊(duì)列:O(1)出隊(duì)列:O(n)線性方式兩種策略2022/12/19堆結(jié)構(gòu)
Heap2022/12/19堆頂?shù)摹皟?yōu)先級(jí)”最高
【數(shù)最小~~小頂堆】上面輕,下面沉;上面氣泡,下面石頭氣泡上浮,石頭下沉“土堆”2022/12/19堆(遞歸定義)空樹;若非空,是一棵完全二叉樹,滿足:若根結(jié)點(diǎn)有左孩子,則根結(jié)點(diǎn)值小于等于其左孩子值;若根結(jié)點(diǎn)有右孩子,則根結(jié)點(diǎn)值小于等于其右孩子值;左右子樹仍然是堆!堆的表示2022/12/19適合順序存儲(chǔ)結(jié)點(diǎn)i的孩子:2*i+1,2*i+2結(jié)點(diǎn)i的雙親:(i-1)/2由根到葉子的路徑長(zhǎng)~logn含有n個(gè)結(jié)點(diǎn)的完全二叉樹的深度:log2n
回憶:完全二叉樹的性質(zhì)2022/12/19堆的表示順序存儲(chǔ)?。?!
012345671236248547305391含n個(gè)元素的線性序列elem[0,…n-1],滿足:elem[i]<=elem[2*i+1],如果2*i+1<nelem[i]<=elem[2*i+2],如果2*i+2<n堆的另一種定義2022/12/19012345671236248547305391存儲(chǔ)上:線性結(jié)構(gòu)邏輯上:完全二叉樹(層次結(jié)構(gòu))對(duì)堆結(jié)構(gòu)的理解2022/12/19如何向堆中插入元素???2022/12/1901234567123624854730539125尾部插入元素后的siftup123624304785539125123624304725539185122524304736539185
defsiftup(self,e,last):#i上行范圍[last,0)elems=self.elemsi,j=last,(last-1)//2#j是i的雙親
whilei>0ande<elems[j]:elems[i]=elems[j]#把雙親擠下來(lái)——對(duì)應(yīng)小數(shù)上浮i,j=j,(j-1)//2#繼續(xù)上行
elems[i]=e
時(shí)間復(fù)雜度:O(logn)siftup——向上篩選2022/12/19如何由堆中刪除元素???2022/12/19012345671338274976654997輸出堆頂后的siftdown過(guò)程左右兩棵子樹已經(jīng)是堆,將最后一個(gè)元素充填堆頂,讓其根據(jù)“重量”自然下沉:效果是把小的孩子向上擠!siftdown——從根開始沿小孩子下行2022/12/19j是i的小孩子
iii的小孩子j
defsiftdown(self,e,begin,end):#j的下行范圍<end
elems=self.elems,i,j=begin,begin*2+1whilej<end:ifj+1<endandelems[j+1]<elems[j]:j+=1#選出小孩子
ife<elems[j]:breakelems[i]=elems[j]#孩子擠上去——對(duì)應(yīng)大數(shù)下沉i,j=j,2*j+1#繼續(xù)下行elems[i]=e
時(shí)間復(fù)雜度:O(logn)siftdown——向下篩選2022/12/19如何建堆???2022/12/194938651376972749012345674938659776132749明確:
最先一個(gè)沒(méi)有孩子的結(jié)點(diǎn)的編號(hào)為:(n-1-1)/2+1=n/2
從n/2開始的每個(gè)結(jié)點(diǎn)沒(méi)有孩子,各自成一個(gè)堆
如何建堆???2022/12/194938651376972749n=8index(76)=4起始:對(duì)于最后一個(gè)有孩子的結(jié)點(diǎn),它的左右子樹都已經(jīng)是堆;自后向前,逐結(jié)點(diǎn)進(jìn)行siftdown操作,將子堆不斷合成更大些的堆,最終形成一個(gè)大堆。建堆過(guò)程2022/12/19建堆過(guò)程從最后一個(gè)有孩子的結(jié)點(diǎn)開始,逐個(gè)siftdown
defbuildheap(self):end=len(self.elems)foriinrange(end//2-1,-1,-1):self.siftdown(self.elems[i],i,end)
#siftdown操作范圍:[i,end)
建堆2022/12/19建堆的時(shí)間復(fù)雜度2022/12/19建堆時(shí),從倒數(shù)第二層的加點(diǎn)開始,自后向前,逐步進(jìn)行siftdown;siftdown過(guò)程中,每一步做兩次比較;兩個(gè)孩子選出最小的sift的結(jié)點(diǎn)和小的孩子結(jié)點(diǎn)比較
第i層向下sift的層數(shù)最多為h-i第i層最多2i個(gè)結(jié)點(diǎn)總的比較次數(shù)為:時(shí)間復(fù)雜度:O(n)建堆的時(shí)間復(fù)雜度2022/12/19優(yōu)先級(jí)隊(duì)列的堆實(shí)現(xiàn)2022/12/19classPrioQueue:def__init__(self,elist=[]):self.elems=list(elist)ifelist!=[]:
self.buildheap() defis_empty(self):returnlen(self.elems)==0defpeek(self):ifself.is_empty():raisePrioQueueError("intop")returnself.elems[0]
實(shí)現(xiàn)方式2:堆2022/12/19defenqueue(self,e):self.elems.append(None)#添加占位self.siftup(e,len(self.elems)-1)#last
defdequeue(self):ifself.is_empty():raisePrioQueueError("inpop")elems=self.elems
e0=elems[0]e=elems.pop()#彈出最后一個(gè),“占位”elem[0]iflen(elems)>0:self.siftdown(e,0,len(elems))#[0,len)returne02022/12/19
初始一次性建堆:O(n)出隊(duì)列:O(logn)入隊(duì)列:O(logn)堆方式2022/12/19堆排序
HeapSort2022/12/19step1:對(duì)序列建堆;step2:不斷輸出堆頂元素,然后通過(guò)siftdown再次調(diào)整成元素?cái)?shù)少1的堆,直到所有元素輸出。堆結(jié)構(gòu)的應(yīng)用——堆排序2022/12/19堆排序2022/12/19小頂堆排序的結(jié)果是由大到小!堆排序defheap_sort(elems):defsiftdown(elems,e,begin,end):#[begin,end)i,j=begin,begin*2+1whilej<end:ifj+1<endandelems[j+1]<elems[j]:j+=1ife<elems[j]:breakelems[i]=elems[j]i,j=j,2*j+1elems[i]=e
end=len(elems)foriinrange(end//2-1,-1,-1):#初始建堆siftdown(elems,elems[i],i,end)
foriinrange((end-1),0,-1):#不斷輸出堆頂,然后調(diào)整e=elems[i]elems[i]=elems[0]#堆頂輸出后,放到當(dāng)前的最后siftdown(elems,e,0,i)#注意:堆的范圍在縮小時(shí)間:O(nlogn)
建堆:O(n)
不斷輸出堆頂、調(diào)整:O(nlogn)
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- IP網(wǎng)絡(luò)基礎(chǔ)知識(shí)
- 氣切患者心理支持與溝通
- 沖壓?jiǎn)T工考試題及答案
- 財(cái)務(wù)崗前培訓(xùn)考試試題及答案
- 2025-2026人教版八年級(jí)物理上冊(cè)測(cè)試
- 2026年重點(diǎn)高中自主招生考試語(yǔ)文試卷試題(含答案+答題卡)
- 2025-2026二年級(jí)科學(xué)學(xué)期末測(cè)試
- 2025-2026一年級(jí)體育期末考卷
- 衛(wèi)生室倉(cāng)庫(kù)盤存制度
- 學(xué)校衛(wèi)生室廠家管理制度
- 2026年《必背60題》抖音本地生活BD經(jīng)理高頻面試題包含詳細(xì)解答
- 駱駝祥子劇本殺課件
- 2025首都文化科技集團(tuán)有限公司招聘9人考試筆試備考題庫(kù)及答案解析
- 農(nóng)業(yè)科技合作協(xié)議2025
- 護(hù)理文書書寫規(guī)范與法律風(fēng)險(xiǎn)規(guī)避
- DGTJ08-10-2022 城鎮(zhèn)天然氣管道工程技術(shù)標(biāo)準(zhǔn)
- 建筑抗震加固技術(shù)方案設(shè)計(jì)案例
- 提高護(hù)理效率的好用工作計(jì)劃
- 2025年廣東省深圳市輔警招聘《行政職業(yè)能力測(cè)驗(yàn)》真題及答案
- 醫(yī)院醫(yī)療糾紛案例匯報(bào)
- 紅外線桑拿毯行業(yè)跨境出海項(xiàng)目商業(yè)計(jì)劃書
評(píng)論
0/150
提交評(píng)論