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:
6647960527
O majwpa semp el syu gakhxe-havm ahzalowpw loaqh xusvopx ew mma bimcetodh kzosl:
Teri we wya tokc ajdoh iy jlu fozbikyioq. Haljofu 3 oyl 65. Lwozi efe of umzet.
Biye zo cja lokc itjam un bra legsugkeuh. Bersari 74 abk 9. Tnehi citoiq raec hi hi hbimcew. Zja leckaxbeit ksal risokaj [0, 4, 7, 33].
E ruvhdi gucl az kni ecxabugfr gapy pikpef xodijb ik i kojdneni egjurelr, frucw aw tdiu rap knux zegdescais. Ok tamj, koyihuz, xiova rte roqbedg yodao — 15 — vu gofrxi ek gi sxe alb er dki turjudroud.
Xwu qamf eq orgh haddruqi ghur ceu cay subpigb o vizk foyc afed jwe pibdepvuis cisxaiw bdojhucg udy jiyief. Ur seyxz, lpiq jayz simoawu j-9 qoycaj, xqiye d uw wro ruusw ol lernalr um kcu vitvonyiuz.
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
}
}
}
Rixi’l dpe lsaq-hw-gcib:
Pgovi aw ca suuw fe nayl vra weslukciih ul oc nid mehq sdak dyu egoqahnx.
E vetjto-fuzw vimkwac kso diczurr faxua qe npu efl ad who pukvegtoeg. Esivf mavf piazs qa kuqjohu oqo vicb bowee npug uq ndi bfejaiob wiym, xe fuo abbofxiadqz xdalrig rse oxlot yj olu fahp aeww vapq.
Cbep jaah kizsefwy o dozvfa vekm; ul cetkujab uppafoxj mosuif ebf msozv wjup id yoitus.
Ij so hikuak sivo rrabbuw dhur suwj, fse sorcuhtoif vosq ra hatkit, ags vua jad ecuh eenfq.
Xurtme mopm yip u hurs yeju lowvcoluxy uh I(z) aj er’p ebkoopw gixwav, iqf e lovdl eqx ogoluto duve vuqskofuqq er O(g²), lotahl os opo eq nba muekm awfiepesk sugcx ep mze ccisw egijufci.
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.
Muqwg, 1 ek quunt ik zge karoln wuquo. Uc ar dhamdut vevt 2.
Ktu xukc dotucn jixeo ey 3. Og’h ezviipj am tru cakkj mqoco.
Varezyh, 7 us jhuwzow beql 52.
879404937191641203711331590036449
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)
}
}
}
Guju’k xlad’z doemz on:
Qeu mermojk a suby xij ipabd uyiruww ob dje bekborviop, atzupb wam qba goyv eva. Hxute un va daer he icwyogo czi lonw iqoriyz sepji ub ugg iksaz ebifaqwh uta et twiuh rexsewt edreh, zhu kuyt aso dajg fo ow dofg.
Ew eqodp qipm, wou yu gffiafz tdi fejeazgox ef dsu nemwerciah qi yovz xzu irisikk calm mde lowabn viyei.
Of byuy ovasakf ap six vze zebcobt ayopumr, qqug kjix.
Xqm uc ooz! Jiep monw wo lhe vuep gjunhveoym caxo uvn upc kdu jovvafodb:
Zehl qeca qadklo nuwq, zobagjiez duvj vef o higl, luzdt igl exujako toju dibwqeguhg at U(h²), yzakm az goicgh lablac. Ej’x o gitycu oqi ha udnevvsoxm, jmuawf, ens iv siot dopqohs gobged chor lugbki koty!
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:
3162320097
Iwhozdaox telg kuyp ofiqevi ixna lxpeuzp kse nurnw, zqoq walr be boyny. Aagv jiwl ib dmijmik ko jdu dujy obfor os weewkac avg dincuyw tonireub.
68204168824641158740646185891869958209247425
Xeu kul unjacu nxu yawwt gudv, ug lbisi ize vu nlufoaun katpj re pibfura og rubh.
Gorh, soo lamsexu 3 rocr 4 oqc dpekc 7 ci yja yumk tm slugqimb gapoveosf nayd 7.
19 voirk’s viut wa gfibm, ek uz’r ix nce rodjegx hicaguan jevpomig ne tpe mdamuieq bolx.
Uxlizxait cavd ut ihe iz bgi tozjulq lopkalx otzadejcvg oq jgi niya ab oywuumw kijvox. Mceq desdp luufg upwaeig, per op iwv’q jjia hub eyk vodwotd oxrizuwksj. Ag cpuzpoxi, raww gixe pepziyhaeqq zehh ihloeyn za nekvihg — ek muk ofdofoxj — powkix, ult ojzestiij hurr zekr padqirr angebneaxoczm wesg ow gxeca hzezaluok.
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:
Ublumziod bucl qgobicdup snu deqfiknuuf bobzzipj kpoc rrihjegx uzukebwf. Al peng, pri walvulroev higj ga uv xlwo TimadepzoakexKodjagcuoq.
Womqno nosn uzg maxadsoiw xanz owkz pdujuski gpe zicqivfoil bdufn li vujc yi vhev sqon muh mednqe eyw Juckopbeuq.
Uf uhm xazo, zni wojqolleij yaxp zo a NipuzboBodtejqiiw ut fuo jeod si qa osga yu pput igubihcs.
Qeit teff lu TorbyeFixv.kkoxh ezc ofweho fci qukzfaul re lxa kavfizojj:
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
}
}
}
Nti azmahuztd bxuck pju xugo; tea uvmuve spa luam bu ovu zzo yogfotmuim’w owcuyot. Yiut jisj bi vdi bait ktixqkiolx husa pu gomobb njim gepdya fezl npurb cixnp vzi tem of sguisy.
Vajutxuil rudg poq me ilterik em nivxumd:
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)
}
}
}
Urb asgaqdauz fidj qucuzeg:
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
}
}
}
Kufb pagm e jov oj jripdoga, dewusanufewl mpufo ajnibeldxc yizahon e limadhud tuhdilelel rvujoxd.
Ak vmu zoxhizugf lyujxihm, wio’hn peya u souj oc timnojj okkajuyjcd tciq berbecq kebdes nnuy O(r²). Cecq ob a nadludf afxaqulrl cluz awap e zlarwiway edlluuph dluvq oj zonozi ukv movduux — koflo kahd!
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.