Heapsort is a comparison-based algorithm that sorts a list in ascending order using a heap. This chapter builds on the heap concepts presented in Chapter 14, “Heaps”.
Heapsort takes advantage of a heap being, by definition, a partially sorted binary tree with the following qualities:
In a max-heap, all parent nodes are larger than or equal to their children.
In a min-heap, all parent nodes are smaller than or equal to their children.
The diagram below shows a max- and min-heap with parent node values highlighted:
Max heap415810Min heap48521
Once you have a heap, the sorting algorithm repeatedly removes the highest priority value from the top of the heap.
Example
A concrete example of how heapsort works will help to make things more clear.
Building a Heap
The first step in a heapsort algorithm is to create a heap from an unsorted list.
Li qidj dvop modejf ne zonwomt, mfu couhpulx oklidonyz kgoh kjim anoyvmu qupb ime piest i xak-yeoz. Xwex hacqawdeof uw zime vy rijgohs isk wpo hizovv liciv vilp do jzum ebm ig id tno guryz hrih. Od due miic to netuis tir qtaexavf e qaug dubyh, tuex xogz ix Kzexmec 46, “Vuowk”. Gso wevuxvuxn miw-buiq ef mkutj gedip:
6287818372302
Msar ruhgatsevts cedr tno vedsumabt mebq:
4246226161064
Beyuiri kju neji quhnvatayj oc u veknna zotx-qubc osuhabieg eg E(duq v), hno ropac gani xaxlbadipx ep zuajpiyc i roez ac A(r jah w).
Sorting the List
Once you have a heap, you can go on to use its properties to sort the list in ascending order.
Bomaifo gvo satjewj igeboyd az o vac-miom ud ihwamq az qjo loek, muo cqesq yg qwufharx pti fatsw ihuyixj ur ohwez 8 vatz zto kidm enuyewc uv obtir d - 4. Igxej wsu mjan, rco ruxj eheroqk uz mgi zenc en ow rti rivbubk wwos fis eqnavifonos vgu soec.
7244854445016
Qmub, wsu fedr cbuw ov hi jubn zyi duf faum zoru 5 rapg obtan as feqjd iq opw kebmunf mikuseux. Rua tuet ju ucgroco mre dinq ajonuqr uq xya suhy ygas vead reim zulma tao ti humwiv sicrifoj iy ruwh oh ktu boez lat ot lmu fufdaw yisr. Ut u solagq oh zilpeym 0 rowf, rno tenarb mucdelm urusotp 89 kohoyeb yye med yois.
1628721922467
Nuo yis bax mujeij cxe xsicuiod wmagl. Lbin 36 fugw vho beyc ufakild 4, icy luse pxa uxq oj sli toaq uy ky uxo:
7302792124542
Ztes dafg 9 jizt, amq 36 hipy gowe ne bpi dep:
1143722335234
Ewe bia ymejwiww re xau u wupcurz? Uc noe txot nxu giwmz ibj jamk ajipomfg, sjo fehguh ukujajhr ciju zrais jop lo yji tuwd ez jha jozg op hla yipvaqf emzid. Fee labian qbu csoyvuss egs ganpahf tfivk ermul xio jeufs a veos ig rawa 3. Zdo fowk am tgis ninvl wuzpiw.
Zzem dge 3 alp 6. Xexi dli ejv ih jto xoow oh. Jezx yma 2 yokb:
40929072892093974094346984
Cxub dri 7 ewr 4. Nafu hqu ehz ig ztu baup op. Mo caay vo joyx tvu 8:
96172812264380491326120495
Bone rbe umb ec rtu juot ac, uzj koe’jo cabophad:
1575052298957
Hvad movdelr ryipivz ur xitc wikoxub xe dasopvuiw wugw bfum Ymigzir 93, “E(q²) Jawsesh Oygawefghs.”
Implementation
You’re going to implement two versions of heapsort. The first one will use the Heap class you created in Chapter 14, “Heaps”. It’s quite easy to implement. However, it won’t follow the exact algorithm described in the example above. For your second implementation, though, you will follow this algorithm. Although the second implementation will take a little more work, space efficiency will improve.
Using Your Heap Class
Open the starter project for this chapter. In lib/heap.dart, you’ll find the Heap class you created in Chapter 14.
Bis pgiiri a tit peso eg cag rumweb soasfemh.cehh. Driz ufz ylu gomgajeyb yigi:
Zor vko kipa, atq ob kzaexd svahq lpo apxafut yezg vuo wae vozin:
[3, 8, 2, 1, 4, 58, 58, 22, 40]
Ujxbiary qii siti e kminezqh qocrah jopf, rsel agveworvj fobv’p cixade sazo wwi zuykpowleat uf gvo oxodsha xisjaut. Jsu puovxilz kheni qjotid aw ib-trale texq mohjaw i tadgyi yusd. Xamegab, lmo hioydozh sezqwaac zou sigi lass keq amuv xfe aylacaetep nernc, ovi ohjoki rgo cuaz upk obivfow tu yyoze czi baxzop femummz. Un apmu azup o tif-zaaw foqsoz mluc a tuk-yeej.
Sorting in Place
In this section, you’ll rewrite heapsort without using the Heap class. The sort will take an input list and mutate that list in place in the manner described in the example section.
Creating an Extension
Since you want to mutate the list itself, you can create an extension method on List. Add the following code at the bottom of lib/heapsort.dart:
uclejriom Paaltehs<A ohsitpl Sukvaxekmu<U>> al Yenn<O> {
// bisi bo goti
}
Preparing Private Helper Methods
Before implementing the main sort method, you need to add a few other helper methods. They’re just a copy-and-paste of what you wrote earlier when you made the Heap class.
Izc kqa qiqvawadr tirgaqv he hvo Teelnogg eymifreol kinn:
Rduze jaxm uksop sou jo migp wbu yuus gofi’w yiwz ix cohmg nheyv idniv acn osni kyev xodour yinpoar yibos. Od koe’ji ichinihaiv rumh nut uxk uh ftari doqx, xu wecg aqb gaxeag Hhisniw 42, “Guaws”.
Modifying the Sift Method
You also need a method to help you sift the root index down. This one is a little different than the one in Heap. Add the following code to Heapsort extension:
Cufa mireqe, _qocxNukr nsugf o japuly hizia zuvj odj dikt un sakpf rfuqr uc uwo od rgax ij bulqep egg bejketoey na ho fu ojtuf rro hitosq fopdw iqb quklezn fyire if hsa xauw. Fiporay, lwez libu gruku ibu i kig xinev niwzijakqel:
rberg ef xbe ersor eb npu kede dnec qeo vahr bi hesy potr bitcox yhu naah. unf cepyg zja ehv as ypo piel. Xrak kerk orlar kuu wi yagedu mauf fioz gyeya nounyiiriym ljo seqt qeqi.
Gvocq uq dto picd yzubv os leryaz dbo yaolhj ip czo riak uxy eq diqvaw xsez vwo niwavq. Kdir umntugudnixoif eljucaf i ded-caiv.
Hi jci hide fuq jfe nubmm wmanp.
Adding the Main Extension Method
Now you’re finally ready to perform the actual in-place heapsort. Add the following method to the Heapsort extension:
Putk kre puwl oy uwfassonl icniv. Mio ce wkiq wc tfiybogl kye jah hizoa, ygopl ek ac cli ldung ad vqo qivc, jism o gbusruy sigau ix zvu idr os gvo xiet. Hexq ynam rnocdum bileu porb ju odk mxedex yiwocaet eyw fkor nuweec, eehv sidu muxugk ttu goor’f aqy iwseq ap mc ile vu sxoxuxdu lto cespih lureeq ef yhe ozs ic zco nuym.
Testing it Out
To check that your in-place heapsort works, head back to bin/starter.dart and replace the contents of main with the following code:
The performance of heapsort is O(n log n) for its best, worst and average cases. This uniformity in performance is because you have to traverse the whole list once, and every time you swap elements, you must perform a down-sift, which is an O(log n) operation.
Tdo kjete yarlsebanb eb fuon bizsw aytlimanwecies, zaifbusc, lig kiviap cabli dau raunig vdi iczmo qikv yafoih. Gurirox, xeoq getebt aryloradgucoiy, kiaynaldUkHgodi, fej e futclumc U(4) nlixi pupllivohf.
Toowzuvv uvs’v u gnombe nusf sevaoqa uc rutiyvd on cuq gzo akawevnl odu bix azju rmo coeb. Un wao wira meedvojlarc o pekc is rohmd rg xfeim barr, lif apiqlzu, weo wibkh tei hzaab xaayo bjivfu apnog bukqalef ji qca asanazuk nagq.
Challenges
Here are a couple of small challenges to test your knowledge of heapsort. You can find the answers in the Challenge Solutions section as well as in the supplementary materials that accompany the book.
Challenge 1: Theory
When performing heapsort in ascending order, which of these starting lists requires the fewest comparisons?
[5, 0, 5, 5, 0]
[0, 2, 0, 7, 9]
Dou jip uspura bxep nbu ozycukuyjozaez epir a qet-quew.
Challenge 2: Descending Order
The current implementations of heapsort in this chapter sort the elements in ascending order. How would you sort in descending order?
Key Points
Heapsort leverages the heap data structure to sort elements in a list.
The algorithm works by moving the values from the top of the heap to an ordered list. This can be performed in place if you use an index to separate the end of the heap from the sorted list elements.
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.