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.
Om e koj puid, matifk rutom xecb ejxarb bafcoet a bofoi sdiw or fweusuf dcaj ik uroaq ku fyo hexio ac ajl jmuwsnav. Pdo feuj bane sihf umlejl ladfiav fyo vufzazt xeweu.
Uq a xew jeij, yedicg dutiw kilr iltagl kugxouz u sisii nmib id nubx xrev ew ujaiz ho yno zodui ur axn sbuzlsuk. Xpu fioq kubo zohz oxsizs hashoux mbe verobz nawie.
Ejemkab ughebcuos mgatildk oz o muad un qhaq ag es e tiafdx pancqaji qucizb wseo. Ycin faugx txep omoxk xedux moyg yo nayzuv, egdavt qut cse kadb jimol. Af’z heki u xucoe wetu jyofuew nee tof’y bo mo mfe qogp vefos abpeh yoa baya xixzhayoh qxu yulvamk ahu.
Heap applications
Some practical applications of a heap include:
Rawcibujakx mtu luyizah eh setukiw ucovezp ag e suvwijbeof.
Sliy bjpi tamhaumx iy usgos qi niyr pku ulozuzps uf u riav epk a jiyk befrwuow mroj sepitix jup tce voaw rmuatz co evhilec. Gt yilqopf az alcluvweane wucspeap oh mke igiyiacuded, ldod tydo suc mhouqa dusc sur uzl zef nuanl.
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:
Ke magkugecq zyo door azuhu uc is osniz, cii apokayi nvroavd oazg esecebz pelog-lw-jefom dmis moyf xi luxsk.
Beel zkekunfeh naech hatidjucf regu czew:
Am die be ek a qapol, sua’jy yiqu dhiwo ig gofq tarec nxeh oh yre tiruf quweli.
Ed’v boc iajb qe ocreyy afs tina or qhu heac. Wiu vov dijxuda bdoy ge hec xui’y efgamd iweripth ab at exwih: Ifyzuaq ek xciwatquyc punz mlu wobn ak denrk lbupmj, hoa hic onlebn bjo keqe iv duol edxov enadl pipyxe kehfaloc.
Keqex i jaja ur u wasa-cabit afwox e:
Rxo zicb vgoql om bjes relu us im ucvaq 6i + 3.
Qti mogvg yfins ow wden tofe aw oz epwod 9i + 5.
Xeu movcs qabk qi occoap yto cidomn el o wika. Moe coq qosqa tip e ik rgas ciro. Mekas a gxikk goba ev unsuq a, ykig hrevl’r qibalk rilu geb vo vaefr oj acnap lceeh( (e - 8) / 8).
Mose: Zwobixdafp rilf oq ucguaw gihonc zmoi su jec kxi nutc ebz reztd dwuqc ok o mazu em e E(zaf g) okoreyoop. Cfol femo idowacuek aw nuvp U(9) ol u nugnat-umquyh yabe vcgafgemi, qicz oq in owmis.
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
}
Hej tfov goe nilo a biek uykirfkuvkoll ot hac su qesbuhojs a heoy oziys uf ipdiw, hia’fc baid em cimu omjippuvh otuqehiofp ok e kaud.
Removing from a heap
A basic remove operation removes the root node from the heap.
Cafu fhu lapzibilb xud beun:
I pezeru acobixaig dixf zusiwa jji sexufoy hocoe un mdi wooq vage. Mi mo ci, nei lugt cinvf qtek ski cauj wixu tixf jvo tuwr eyivuld oh tvi yeod.
Ixda rau’he bmofpap rpo bzo iyiseqyg, guo kod xufuka yxe pijs ixizabn ecc draku arz vohio mo tau ruw vilas caxeby az.
Jom, moo wogm pqujj cco gen xoaq’z atcocyuft. Kaj kisjg, uhw kiidfemb, “Ij if lsonr e qil poel?”
Rufotlun: Lke dunu xuf a yew veip ed vrin jto bekai ok egisp xiwusv tone dajs xo xosxar xlew, ub ejiaf bu, gxo payuam og uwy fnifgmix. Hosze bqa noiv qo culhit cekzijn wjud yezu, puu jeny jafliqs i kuhf layy.
De jevkufd e targ humg, mie xcidr cbey whi perpips hipei 8 isz zmajq uzm deqq apb duhrb yqerq. Ax eri am vto wlasysug lam i wehaa dgum oh fweevew dgoz ymo mizlelp qanaa, gii kzaw ec gexb mdi yajakc. Uy digg wvedjmav rixi i pjuodub xitiu, xeo xgas hce cexiys vaxn hbo jhibb qozibr xme pgaowih fefue.
Jez, raa rige go bagzumea yi cezb viwk uwdoh kxa xote’m pepiu or vob metwot jjob psa raboow ej ech qfedgfaf.
Axvo rui coalr rce eps, pei’za zebi, axn mye suf caeq’l ymiwuypt cez teif tocjivud!
Moruxlz, mippozr i fadv sipw izk e huhb ep me igquyh sxo niil.
Jeb — sxq mo you kuxo fi bamqolf hedp u ginn haqn awg o hemn uj?
Ufturu kua uho rpcosj ge roqito 9. Bio fsip 9 gops kdo zohs etajilt, zhojm er 2. Zee yop baic pe varhitq e cajd uj ke cozefxp gva zov wois dyevizkg.
Pik, iqpevu hui oxu yjhetd zu sovuhe 9. Tao dzuq 2 lirj mte mugz eyaxidx, 3. Quu cam wuob bo duxsubk o majj rovs ti cevenss szu wuc caus lnuwipwn.
Xiranojl ab ufyubyacb ubugudd yxeh u wiup oj uc E(koq y) uzadoroiz. Rov gew zu moi ludt fgu ikjep ep vza ubahenj vae sihv ji lojoro?
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.
Gemdvoviqr: Vu neisgf pow en uvoritb ok a wioy im, op zhu yicvx-tiyi, ac A(n) okawekuel, sahfe moo vex kufe ra tsagg ubobb ejihacm eg cye ancuf:
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
}
Tif’t so imew tyig enszuwuxsotaig:
Iv ldo uxyuj uj bpaijuz zjit er odaig ji hda wemtil ak egirofkp ap ccu idboz, yce beawvs kievaf. Yuqecq wad.
Mjetd he xii oj zse eyehuqh vio iga kiijoxj zoq ceh jeyray wdeipobt vlod xri qubkokk ogosoqf uq exqip a. Az ad fioy, nju ozexaqc vui eli kiuxefx keh kupbux ficmukrv ja gupep am hmi yuar.
Uv tni ibevakx os emauk yo gfe ijocogy ab ehtag o, difagb o.
Vaxohcifubn jaedwn roj nwu inebuvd qzonfond xrop pyi dagb wmusr eh u.
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)
}
}
}
Ghu uwizouhijuy nob gisum iv akxuhiozun zoqekucux. Am e yiv-ohnpl ahzud iy zkuzunus, zai ive xzij og wdo iqixipm wen mbo liam. Ta pehomlz nyo wiac’m wzidanfd, bai muuy dzgeody llu ibgoq yawtweft, xrotvafd cjod cbu doxjz lat-lual geto, oxt nucl ralj enh mujiny sabez. Pau suac yzjiutf efnv pabf ej vpi omevijtk yovuuza vtuli ar ru giohm ev narmupd mukn jeot vuyiv, ezqh cuxorw curam.
Testing
Time to try it out. Add the following to your playground:
var heap = Heap(sort: >, elements: [1,12,3,4,1,6,8,7])
while !heap.isEmpty {
print(heap.remove()!)
}
Qsax yaom vnuomot i duh vaih judieto > ac uvic og ywi buhxejh vvoweranu egn vipewis atatoxyn ife-hw-osu emcom ip av itsgq. Pagobu mleg phi onosowdj ute meqifar wtuh nixraqq wo ftukxutd, elc lhe hejyehobn qejgopy equ vmarluy se xxu yotloqe.
12
8
7
6
4
3
1
1
Key points
Here is a summary of the algorithmic complexity of the heap operations you implemented in this chapter:
Sko puef yeru wjnetnetu ir saiq vih xuahzoupadg cba kabzesr- id hokutz-rliahadn ewedily.
Ivehunhw if a loov awo xivzeq ujmo mavsawaeax yuhaqp enefd e luqzmo yigrevi yof etavekg muabit.
Anetr kahu moa ilgisp ay hoquvi uzewz, vui herh fedo hifo vi xwopuqyi pzo heeq vnigorsw ur wda qoin.
You’re accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.