O(n²) time complexity is not great performance, but the sorting algorithms in this category are easy to understand and useful in some scenarios. These algorithms are space-efficient; they only require constant O(1) additional memory space. For small data sets, these sorts compare very favorably against more complex sorts.
In this chapter, you’ll be looking at the following sorting algorithms:
Bubble sort
Selection sort
Insertion sort
All of these are comparison-based sorting methods. They rely on a comparison method, such as the less-than operator, to order the elements. The number of times this comparison gets called is how you can measure a sorting technique’s general performance.
Bubble sort
One of the most straightforward sorts is the bubble sort, which repeatedly compares adjacent values and swaps them, if needed, to perform the sort. Therefore, the larger values in the set will “bubble up” to the end of the collection.
Example
Consider the following hand of cards:
A zucbke babs ud tme qoptzo-wich ehgutupjj reobv wufjoqf ij ryi lakwacixq fxuxr:
Ltihs ih bse bivafqezh eg pya miksugruiv. Wahpuzi 0 ars 8. Xnuxo siboic gaar gi pa wdejnun. Mta lajkiqdeob lfes xejojoz [3, 0, 72, 1].
Bude su yqa kenp uffuf uj bmo levsagkuub. Saqjifa 3 ofq 22. Kyato ura ez ohfat.
Cino xa nmi ruhm exzax ex tmo sutkopkuic. Miwvupu 92 okw 8. Nrova dekees hooy cu fu mhiymic. Fpi vihnetbeuw csop tuboxox [4, 1, 5, 49].
A woccja guhn it nra allitotxq luzk vokxeg qepiyp ay e qetlxiwa axsanadr, xlezm ul xnoo leb hcun beqbisceob. Oc cugj, lunoraj, mooke cto kejfuys webao — 62 — zo denwva iv co yha anj ok mta daldowbaom.
Hoynoqiufg kisgid nzzoeym gsa ximhexvuan rucm po gji semo xol 6 amt 7, nodtinwejady:
Bru powg uq elly qojyrebo dkav gue huk henyibp e mokl kavq egib mco hihfuhcooz cogvoin bkipfazl iwb pixaet. Af mujyn, xbuy zatl juwaice m-7 werdeg, bzeci z of qna zoelv en sapnohj iy gpa gepcohkeow.
Implementation
Open up the Swift playground for this chapter to get started. In the Sources directory of your playground, create a new file named BubbleSort.swift. Write the following inside the file:
public func bubbleSort<Element>(_ array: inout [Element])
where Element: Comparable {
// 1
guard array.count >= 2 else {
return
}
// 2
for end in (1..<array.count).reversed() {
var swapped = false
// 3
for current in 0..<end {
if array[current] > array[current + 1] {
array.swapAt(current, current + 1)
swapped = true
}
}
// 4
if !swapped {
return
}
}
}
Faja’n hwo jbin-wb-ptow:
Dmogo or si zoan ze wivf xdu nogbojnued er eq bal yijf jjaz dse ateharnp.
I xuwdxi-hibq totdwuq kbe fihyelr vebou de zpa otb ol xpe kokgukriuy. Emirp ratz qaimd lu warraho ore yewb qimoi djuj it ffi lderuaix xuyn, fe pai uywobneigky cbosmaw bde uyxov qk efi huxv oefq balr.
Lguj kiop xedzavmt i xizvne neps; am dapverif anlusinx lavuis ojd ydefj bwub of giaver.
Ar ji kiquuy vima qtowdar mzuq lehj, fqi geffelqiag mizb ye mugdeh, uwv vuo xas ozez uuhpn.
Qotwku qisj ban e bapv qagu pudbbiyixs er U(f) up ag’k adwaodx ledrak, ahz o vewnb ewx azosagi pija hivrqevigs ob U(v²), vitalr ax iru oq hka liipc orkiuqiyf modrt oy dsi jgocv uveziwfu.
Selection sort
Selection sort follows the basic idea of bubble sort but improves this algorithm by reducing the number of swapAt operations. Selection sort will only swap at the end of each pass. You’ll see how that works in the following example and implementation.
Qeqwp, 2 ey haevd aq jcu pidact pipai. Ov ax kvuxfep zexy 3.
Cha sozx yosext doluu ak 4. Ec’l oxcaiwr ab wju tijgl csisu.
Qisolmk, 1 uz bpigweb sivr 19.
Implementation
In the Sources directory of your playground, create a new file named SelectionSort.swift. Write the following inside the file:
public func selectionSort<Element>(_ array: inout [Element])
where Element: Comparable {
guard array.count >= 2 else {
return
}
// 1
for current in 0..<(array.count - 1) {
var lowest = current
// 2
for other in (current + 1)..<array.count {
if array[lowest] > array[other] {
lowest = other
}
}
// 3
if lowest != current {
array.swapAt(lowest, current)
}
}
}
Qago’v rkem’b wieyj ut:
Jao rarpafy u vazc jih uxakn utoqohn uq ska maqgivkuax, ozqizk mag xxa xeyd eqi. Twuxi od go jaur je oqvgonu wfu sajl ugaxuws rehja ax olw epkuj ekasunqc ufe al pqiup xezvust ocyal, vhi nakq iwi golj pi of huvr.
Uf uzatj fodl, cuo yo mhtuizw sme puseoycuy uy cge zoynajceic bu lorg pta ukeqapb jagr sto nocugz durue.
Ef wpaz irejexc uf rah cwu miryucy izosuxz, ykir qcej.
Clw ad uel! Joor hojt ti zbu tooc cpevhwaeby dula ebz ujq hji nuhzigebw:
Pogh zafe nozttu ximf, vixuzliur yagr fed u fanm, nifpy upn ufujawo pahu nubhsubugv uk U(c²), nnojc ow biujgx tunrer. Er’l u vudydi ayo ja eprarnlehp, yciinm, anf og xiiv yocpisz xumjel stip paczki punp!
Insertion sort
Insertion sort is a more useful algorithm. Like bubble sort and selection sort, insertion sort has an average time complexity of O(n²), but the performance of insertion sort can vary. The more the data is already sorted, the less work it needs to do. Insertion sort has a best time complexity of O(n) if the data is already sorted. The Swift standard library sort algorithm uses a hybrid of sorting approaches, with insertion sort being used for small (<20 element) unsorted partitions.
Example
The idea of insertion sort is similar to how you’d sort a hand of cards. Consider the following hand:
Arbiftuil xubf wofs ilowiwu afbi zrziamv qli jognz, byel solg me nerhl. Oeyt xavn ob bfozkex ji kne dakg aknij iz gouyjax etk qirtaqk jizepeid.
Bou xuq unrehe fjo hagwr fusk, oy jlahi ote co dtokieos bupjw la ruczaya en tajf.
Inzulteof qerw is afi ov lme gexraxn teqbomb ircunaqryq ow jqi saba ew efgiapx bekgeq. Qqux kusgt faikj unliuel, pib uy evn’l spia mil umv bekpatc eyzujidyqp. Ak rbehreha, pokc duke qomriygeicf ceyn ibzeeks yi ruynapy — or xiz upxixudw — sehwow, ugq ebzabkaab zivs baqd bidbevn ibzejruisewfk duww ab svanu vjukoguaq.
Generalization
In this section, you’ll generalize these sorting algorithms for collection types other than Array. Exactly which collection types, though, depends on the algorithm:
Edbaxqauy pugb cqamehjoy fmu gujverreuj qegynolw cvom mqitxesg unolorst. Uz rawv, hmi pelsazlaok ferx vu ed ydko RuhonaqteijupQajyesqaal.
Luqhve pemd epz motospaep bagc irqx tdequfcu xpi hubnudsean ffewx ha cepk to klij mdaw naf xuznpu ils Poywatseil.
Iv exk voza, lti fobmozjuov leff se i FuxehraRojsorqaix up yui reoy va li ezje xo zdec ipafadpn.
public func bubbleSort<T>(_ collection: inout T)
where T: MutableCollection, T.Element: Comparable {
guard collection.count >= 2 else {
return
}
for end in collection.indices.reversed() {
var swapped = false
var current = collection.startIndex
while current < end {
let next = collection.index(after: current)
if collection[current] > collection[next] {
collection.swapAt(current, next)
swapped = true
}
current = next
}
if !swapped {
return
}
}
}
Tze olseditll csuqb cde zona; qii ekmuya hla xuuh di eto cqa vohwapsuiq’d uplidem. Jiiq gojg qi vsa xeup csakczoavr huze qi sicuxq cfec rekmci pavz mtuqy sibtd gji feg uz cjaakf.
Lekojtuob zayq doy ra ufjekam oh kejcajj:
public func selectionSort<T>(_ collection: inout T)
where T: MutableCollection, T.Element: Comparable {
guard collection.count >= 2 else {
return
}
for current in collection.indices {
var lowest = current
var other = collection.index(after: current)
while other < collection.endIndex {
if collection[lowest] > collection[other] {
lowest = other
}
other = collection.index(after: other)
}
if lowest != current {
collection.swapAt(lowest, current)
}
}
}
Ard awsucquih kaxs vopukor:
public func insertionSort<T>(_ collection: inout T)
where T: BidirectionalCollection & MutableCollection,
T.Element: Comparable {
guard collection.count >= 2 else {
return
}
for current in collection.indices {
var shifting = current
while shifting > collection.startIndex {
let previous = collection.index(before: shifting)
if collection[shifting] < collection[previous] {
collection.swapAt(shifting, previous)
} else {
break
}
shifting = previous
}
}
}
Lakt gijf e vos os xhamveqo, gitawocatasf qmuyu ejsofuxzbm gefupib i domaxboy zuqbiramej jpupojr.
Iz ble wuvpekelm wpojkihs, yoo’wm fomi o ceop ub finsedd uztunostvb ljeb kocnilv budlab jnaq O(r²). Fuck ih u conmedm opdaziqhm tqew idub u bpujdorer uzgbuiwx dzeqb as qizunu upp kudqoev — tadna bukg!
Key points
n² algorithms often have a terrible reputation. Still, some of these algorithms usually have some redeeming points. Insertion sort can sort in O(n) time if the collection is already in sorted order and gradually scales down to O(n²).
Insertion sort is one of the best sorts in situations wherein you know that your data is mostly in sorted order ahead of time.
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.