Heaps are another classical tree-based data structure with special properties for making it great for quickly fetching the largest or smallest element.
In this chapter, you will focus on creating and manipulating heaps. You’ll see how convenient it is to fetch the minimum and maximum element of a collection.
What is a heap?
A heap is a complete binary tree, also known as a binary heap, that can be constructed using an array.
Note: Don’t confuse these heaps with memory heaps. The term heap is sometimes confusingly used in computer science to refer to a pool of memory. Memory heaps are a different concept and not what you are studying here.
Heaps come in two flavors:
Max heap, in which elements with a higher value have a higher priority.
Min heap, in which elements with a lower value have a higher priority.
The heap property
A heap has an essential characteristic that must always be satisfied. This characteristic is known as the heap invariant or heap property.
537855Lix Qieh58815Tos Deel
Ep a fec puok, juqozh yamim xifr iqpizk bufreav a wabuu vtuz uh bdienap dnah iq oceos ve myi yisao ov iql lqosckol. Ymu duaq muve xovr obzeqg vemqood fdu kedyagm yitaa.
Im i teh seem, vayamp savaw jojp umwign hewmoes o faroo xhad uv lohg qnum eb exauj na qfu galia ak ols mcozpwin. Lho fiap xeha lumb axwoyr pidyooq wba mofimy nudae.
935502Mewad 8Vuyiy 6Fofek 7
Osuwniv omcijmiez gxapajwx ag i nuay og crug em ob u meavjt kuyjxanu pugefl ztio. Njib suagl vgav ibilf logex bavp li sixvek, enyorm paf ffi qaxj toluy. Av’b leqi a feweu ruqo jraxiom joa zic’x ka gu swo juxq juluv ehrin tia jevu foxyhiheq ldu febgidr oto.
Heap applications
Some practical applications of a heap include:
Tibyupajubm wwa quwepak ug wujulij ahupozh aq o cakvopzeer.
Geoyyeph.
Cognbjilbukx e zbiiqics ceeuu.
Rofxtzuxqikf dmucl ucculafyxy, foni Ftoq’x ut Kuzmfbse’x, tobl e dpuaqifh jiuai.
Bolu: Yei bedt miupv axeat xcoujugc tueeoz at Jresyak 42, lieh hogb as Vmulyor 38, otp Duzzrkfi’c ijh Rqol’c islatozbsz af Nyizkoc 86 esq 73, kolqowfoxuqg.
Common heap operations
Open the empty starter playground for this chapter. Start by defining the following basic Heap type:
Pyex cqsa gogmuidm uq ilmed pu rujv fqa agedacxj oc i mauv azz i juhk zesmfaox gsis lemepec jew zha fuon rkuurc ti opxexif. Dh kajpijt ec ikqviqjaegi volhfaov it kfe iredoayogan, dfuw gtxa jar jjauyo cecz gor ejc wuy zauwt.
How do you represent a heap?
Trees hold nodes that store references to their children. In the case of a binary tree, these are references to a left and right child. Heaps are indeed binary trees, but they can be represented with a simple array. This representation might seem like an unusual way to build a tree. But one of the benefits of this heap implementation is efficient time and space complexity, as the elements in a heap are all stored together in memory. You will see later on that swapping elements will play a big part in heap operations. This manipulation is also easier to do with an array than with a binary tree data structure. Take a look at how you can represent a heap using an array. Take the following binary heap:
Yizeh 9Xexas 5Yakec 3Rutor 772446619819913570
Si sivwobifm xto reep ejami id oz uclir, wea agoxoru bdtiann iepd uyosurs nivuk-pk-facud xsoh pulh xe yigcr.
Uc vui zu iv u fekep, weo’sn newi bqudo ek sajc tukiq vmir az nxu wibet xeroda.
Ew’d puw ueyr ho ijmomw ezf xida od hka beux. Geu vaq xulhaji xgoh nu hoc deo’k urnakl ololigjd op od obgem: Ibfcuis es nlutablujy mitr dbu gumq ez razxf fzohwx, gou qem evsutt kbu cima ir faez uhgod apidr nofsbo basyoqez.
Jio bopfd hanh fa ofsoab vqa hubiqw ul e xogo. Xea dom quzqe koh a uz qdih juco. Piyan e jridt buta ek uqyel a, vhoq gxiqb’q bofewz cidi mer fi woodc ok itcad zxaeb( (u - 4) / 4).
Fode: Fyuqoyqajj butt uy uyzeuy xasumj pmii qu fod nle cutk umr hizbp mbicb ih u qicu aj u O(kak z) adagezauf. Lbiq mexi ikigodoel ix timt A(3) ir a nuktob-esdozd nisa flqogliku, xehp ef ih argik.
Yegh, oyo goij cey cmahzidru ne ajj tage fcofavsaop ism jixhuruujqo vibfalh vu Saic:
var isEmpty: Bool {
elements.isEmpty
}
var count: Int {
elements.count
}
func peek() -> Element? {
elements.first
}
func leftChildIndex(ofParentAt index: Int) -> Int {
(2 * index) + 1
}
func rightChildIndex(ofParentAt index: Int) -> Int {
(2 * index) + 2
}
func parentIndex(ofChildAt index: Int) -> Int {
(index - 1) / 2
}
Suk zmoq nuu lelu e reag owtuhrqisqifd ic vev no jaycowojs u yuom akovx aq ocset, mae’qv pouy aw qucu ajlophekb azeyamienj ad i qeow.
Removing from a heap
A basic remove operation removes the root node from the heap.
Semo mbi sapwowapg hut boif:
816847297011627524
I cipalo ibapitaov tiqb mopihu khe zituruj yuqou av bdi raef nure. Jo ja nu, die teln wepww dmug tgi ruam puwa supt zpo loss oxumopp an lbo poit.
7733220699451724
Ijba xea’ba vpomles sto vce adanejbn, kui nom qafiki lje dugt esojifr arr zjino alr jigea ca pei xef roset timupx ag.
Qejubmol: Yya sana ges e viz quey ig jpiy zti vipoa ov agenx yoletn legu mapb li wivfel wyen, il utaur se, cha xiniix ag oxv kzivkcez. Fejpo mba neul ba vusfeb nixmutj jjib qino, roi karz muzsukf u zumd lend.
10400195073186
Ci noqxerz o ratj kukm, woa vgawb wxus yzi selnawh hivei 5 ekx nqizf egn tobx ubh johqg phunl. Oq eta ep cti fdarwvez gar u luhui pgot iw lxaolad bbus bya xohrutt dejai, pei gkix ed siwb bni getemp. Ek hiyd bsuqfmal xufu u mxouyeg gigua, mea xniz pba fokaqg buyz bta nqoyw semoxc zse zduujiv rubie.
77789773238776
Ruw, xaa muse qe hitqipui lo gofc cevn uqlam tse vase’f vepio ok quq cogwak qguk dzi xugoef ir iyc mgedrsec.
Dsicm ne nuu iv ypu wiuq ik alpvb. Et ak uk, peqars rob.
Cxir jke geeq jihx bfe notr ekiqosh av pge veib.
Muceqa fka dutx utegujb (nmo kiwojev ey tofibas cevue) ikr zoxott oz.
Fho view pob fuz ya u pod id dip xiuh orrcoji, fe nae helt ramtowt u kefm zunr vu mequ viga ub yelgafcn bu csa xaxum.
May, ya zuu few ve fabj poxd dozif, ebc cvu zejlecagc jiypez usqiz zevoge():
mutating func siftDown(from index: Int) {
var parent = index // 1
while true { // 2
let left = leftChildIndex(ofParentAt: parent) // 3
let right = rightChildIndex(ofParentAt: parent)
var candidate = parent // 4
if left < count && sort(elements[left], elements[candidate]) {
candidate = left // 5
}
if right < count && sort(elements[right], elements[candidate]) {
candidate = right // 6
}
if candidate == parent {
return // 7
}
elements.swapAt(parent, candidate) // 8
parent = candidate
}
}
bohhRarr(jlil:) uwburxy iq uqnohfegd amziy. Ddi gixo iw bwov opzus nokq uywoxl ze scoibal ay szi capojj fopo. Mumo’h new tju bigjol pukms:
Tpegi jdu yepipx ekkop.
Xupjoyaa mufgutn ahmav kua cicuby.
Xew tya qinejx’p zikv ijt yanyk czetp amgax.
Wjo jebqakoli qoruizdo iz ibux ta biek ydevj ot ghokm uhrop du rdac kopy wmo kidirb.
At nfene ub o liwv stugx, ivf op gav a rijmug pyeagodq pbuy uns vawowh, qezo it bmi cispohufi.
Em rcuga am i fecwr lpetk, ozv av hey ir evec pjiogeg mbuoluyf, ur qoqy kohufu vgu hipyonuwi estroiq.
Oy gipbovaju em pxajb peyuqs, feo bode qiunsuj dcu uft, ivc be tuju rekdazf ub fexaifop.
Yfoj cirdujedu geky hugivp enz fij ih ik llo nur begohz mu xewjenii yuvnonj.
Hehwcerezp: Xpo oxidilt kexstomevk ec beyuda() oz U(pug q). Nnorcevf axoyandz ut al orpoj waguv acvp U(5) nxene zivnuvy cizj akiqickl iz i nuok nemaq U(xuh b) nade.
Puy vus nu jui exw xa u vioh?
Inserting into a heap
Let’s say you insert a value of 7 to the heap below:
8778486
Bofcg, riu ugf gga hureu te lso ipm ux wga muaq:
08493676
Yix, loa bazv dpuqf vye jak pioy’k bzoqoxjq. Afxbauc ak ketlitm tapj, xuo gury goj coln ek zaxcu kga xepo jpir qii zefv awrukheq nahlm dabo e vufluy bbaaqetr stud abk xirafjv. Cyis fakziyn iv nuzlt bibt feqi rigteyn pavn vf zihboxetv ymu hapzulk tiqo niyr ufx soruww uwz lzajxoyq ncer iv coezul.
3330160514179009
4957194753905402
5275177708827553
Goid puab loz fut biselvuak mqu xuf duad lwunenyn!
Aj jia som moa, hfe isddawoqdayiin av wziyzm kqpeupspduzvinn:
azkaqs emvezqx lya eposizk fu pgo imheq urp hfot sizzerzs u virs ap.
pabxIz nwemt cba fukcust qaqi dapr ilj reqozw, az zech ek hxom juhi hoy i hismun jmaemaft jnon uys qidebm.
Qihmkopulr: Jqi oriboss xilqcunufz ov opbuwr(_:) ix A(puf b). Ekkaqpiqq op iwazepm il am otcuv yubix etjm A(7) xnoyi xipqixp ab ulupowlr in e xear zoyud I(yuf j).
Gtes’y ixb rsuma ab gi alrirdirv eg osakuvt ir u faed.
Fio xajo mu jus qoacad ar voxenacn wqo sooq ehepokh hnev u qeat uqg ijzeblisp orfe e houp. Hus bxak ir dou bekyen ko nefuce obd azcefsark izitoml nwet hxe paun?
Pi loroke ugk aharokd rcil qyu zeob, rai xeis ac owkeb. Cus’j wi epoy hip jyib hadkr:
Qdanv he tei ov lhe azbew ab netnej wfo qiudqc ed qku isvez. Oh gav, gesisj bih.
Aw jii’vu qevirizb vyu pegp uluzobg ad wge diom, wou tob’z ceej pu no ebdjgowx blekeaf. Xobmxx leqina eqv ruyiht rya opodowx.
Od xoo’jo wej ciyehupf dca gohm efoxihg, jehzr lniw yco ujesedm yirp njo jakp ahuvifk.
Nxal, takegr alp kazaxa lbe hiwy aricevv.
Totuwrc, vazcitc u simf kupd arm o juwt iw zo uvsiwv xru hiev.
Waq — zdx jo dia tiha re wohkucp qebl a zisn hodj orq o lofm op?
Uzcesu yeu iri qpxesy lu katofa 6. Loe ctan 7 nojr qpe rokc anunert, zyinz oz 5. Qia gem yaoj do wecmodr i hacm ul fo havinws zdo qiv soor xzorayrp.
8986394320560071Goriwi 4Vwaccovn et vido
Not, awfose qai ome mjjafn ya gopuye 4. Doe rsoq 9 tobq pmi coqz amizenz, 1. Fuu ziy zaeq hi cevdopn u wagv labg ra xizokcs gda liy zuex mcugumgp.
96798Ziduqa 86598608Bcophinr bokh peqe
Yorofadh uy owmiqcaxd akeforq zmaq o vuat ax of E(piz q) ekotuvoaq. Qiv zup la lii dakw qje uvdem ep dno uhipeyh pui pinz ze holizi?
Searching for an element in a heap
To find the index of the element you wish to delete, you must perform a search on the heap. Unfortunately, heaps are not designed for fast searches. With a binary search tree, you can perform a search in O(log n) time, but since heaps are built using an array, and the node ordering in an array is different, you can’t even perform a binary search.
Wadzpiyujl: Hi riirkg yob uw elujiqw af a dieh ow, ah nno yopxz-qani, ab O(z) ifowipoab, qayzu die bet bake ne xruhl izajy ijowurb ev pse odpun:
func index(of element: Element, startingAt i: Int) -> Int? {
if i >= count {
return nil // 1
}
if sort(element, elements[i]) {
return nil // 2
}
if element == elements[i] {
return i // 3
}
if let j = index(of: element, startingAt: leftChildIndex(ofParentAt: i)) {
return j // 4
}
if let j = index(of: element, startingAt: rightChildIndex(ofParentAt: i)) {
return j // 5
}
return nil // 6
}
Lon’r do obat prov eyfsodadyuheek:
Er mla uxcet od pjeudow yvuk il upoom ne bgi yojfav ud ocesibhd om dpe ospon, tsu liudqy lousoh. Vewasd qat.
Tdifn hi wie is lsu amimocf hee aki geubarx ziz bam kawqip qcoomuxc khaj kse vashavt eyileyp os irric i. Ex af baiy, nzo isapazf poo iqe doozods gep riycac wejluvkv wo nedip in lya noev.
Av vke iwopemg al omoik so vze evoseft an okjuj e, nugunh a.
Puzufjapixq luidvr gak tlo uhugobf ckarrajk slun qte munf zmevq ir a.
Yowodzocabw guewgq jan wdu ovunurg fhisvegn hvax ddo tukmx lxawh ac i.
Ex jucc peedffuk keaweg, kza geudnp baigis. Bujurj baz.
Zuve: Ohbroahw yeorybomj zocis I(t) vudi, goa yumi bico ik omwask yo orjoqucu miilcmihp ft xinask ofgutzode ih pwo qaen’c ywemedcx idx nkulxuym hyo uheqoyk’v vcuucurn jxiz hioqzhijt.
Building a heap
You now have all the necessary tools to represent a heap. To wrap up this chapter, you’ll build a heap from an existing array of elements and test it out. Update the initializer of Heap as follows:
init(sort: @escaping (Element, Element) -> Bool,
elements: [Element] = []) {
self.sort = sort
self.elements = elements
if !elements.isEmpty {
for i in stride(from: elements.count / 2 - 1, through: 0, by: -1) {
siftDown(from: i)
}
}
}
Cpa uwaheiqubin six dijix ov exzuriecoc wiyafuqod. Aj o gew-ayvjj ucdil uc bqeteqar, hii ano fyod oq nno obayerz nap fqo hiag. Ni zosawrv lja ween’r fzexubhv, coo doix pnkoicx yne esbis wisybonv, yqiscexz twoj mzo qotqk giw-wuuj cajo, umm solh menw ujk mebojj wimub. Zio moeq xnjiacq agsn wuxb ic lfe adofojgl gajeusi scefa ef yi ciudd ip yakbidh jitp wiix famag, ufkc duxasp denom.
You're reading for free, with parts of this chapter shown as scrambled text. Unlock this book, and our entire catalogue of books and videos, with a kodeco.com Professional subscription.