When would you ever want bubblesort? (2023)
Posted by atan2 5 days ago
Comments
Comment by Syzygies 5 days ago
He claimed that choosing a subset of k integers at random from {1..n} should have a log in its complexity, because one needs to sort to detect duplicates. I realized that if one divided [1..n] into k bins, one could detect duplicates within each bin, for a linear algorithm. I chose bubble sort because the average occupancy was 1, so bubble sort gave the best constant.
I described this algorithm to him around 5pm, end of his office hours as he was facing horrendous traffic home. I looked like George Harrison post-Beatles, and probably smelled of pot smoke. Understandably, he didn't recognize a future mathematician.
Around 10pm the dorm hall phone rang, one of my professors relaying an apology for brushing me off. He got it, and credited me with many ideas in the next edition of his book.
Of course, I eventually found all of this and more in Knuth's books. I was disillusioned, imagining that adults read everything. Later I came to understand that this was unrealistic.
Comment by refibrillator 5 days ago
Comment by willvarfar 5 days ago
Of course my intuition would be that you can do a random shuffle and then take the first k, which is O(N). So I might be misunderstanding.
Comment by chopin 5 days ago
Comment by tialaramex 5 days ago
Comment by minitech 4 days ago
Comment by itemize123 5 days ago
Comment by Syzygies 5 days ago
Their 1978 second edition works in exactly the memory needed to store the answer, by simulating my algorithm in a first pass but only saving the occupancy counts.
Oh, and thanks (I guess). I really didn't expect to ever be reading FORTRAN code again. One learned to program at Swarthmore that year by punching cards, crashing our IBM 1130, and bringing the printout to my supervisor shift. I'd find the square brackets and explain how you'd overwritten your array. I even helped an economics professor Frederic Pryor (the grad student in the "Bridge of Spies" cold war spy swap) this way, when I made an ill-advised visit to the computer center on a Saturday night. Apparently I could still find square brackets.
Comment by addaon 5 days ago
Comment by jononor 5 days ago
Comment by hwayne 5 days ago
Comment by amilios 5 days ago
Comment by addaon 5 days ago
Comment by Pannoniae 5 days ago
It's basically asymptotically approacting the correct (sorted) list instead of shuffling the list in weird ways until it's all magically correct in the end.
Comment by NooneAtAll3 5 days ago
which ones you have in mind? and doesn't "nonsense" depend on scoring criteria?
selection sort would give you sorted beginning, cocktail shaker would have sorted both ends
quick sort would give vast ranges separation ("small values on one side, big on the other"), and block-merge algorithms create sorted subarrays
in my view those qualities are much more useful for partial state than "number of pairs of elements out of order" metric which smells of CS-complexity talk
Comment by zeta0134 5 days ago
A few other algorithms would have fit the bill just as well, but bubblesort is perfectly adequate, so that's what will likely ship. More complex algorithms end up losing out due to greater initial overhead or larger ROM size.
Comment by jeltz 5 days ago
Comment by zeta0134 5 days ago
My goal is to stop working as soon as possible; this is a 1.7 MHz CPU and it has many other tasks to perform on a given frame. It's hard to appreciate unless you sit down to actually do it, but on a processor this slow, the scanning of the list and the comparison of depth is not cheap. It's computed on the fly as we go, there isn't spare RAM to cache it, and it changes every frame anyway. All of that makes the scanning and comparisons way more expensive than the eventual swap.
Insertion would be ideal here for a freshly spawned object, since we already know it is out of position and merely need to find its destination. (The work to shift the rest of the list down isn't super expensive, thankfully.) In practice this is already a big enough visual change that the player doesn't have much time to notice a depth error before it corrects itself.
Comment by GuB-42 5 days ago
But this is a case where theory doesn't count as much as having an acceptable result. It is typical in video games, if it plays well and looks fine, who cares if it is incorrect. Here I guess that sometimes a sprite appears on top of another sprite when it should have been behind it, because of the early exit, but while playing, it turned out not to be noticeable enough to change the algorithm.
Comment by mhandley 5 days ago
Comment by bxparks 5 days ago
Both Insertion sort and Bubble sort are O(N^2). Both are stable sorts. Insertion sort consumes only about 10-20 bytes more flash memory than Bubble sort. It's hard to think of situations where Bubble sort would be preferred over Insertion sort.
Shell sort is vastly superior if you can afford an extra 40-100 bytes of flash memory. (It's not too much more complicated than Insertion sort, but sometimes, we don't have 100 extra bytes.) It is O(N^k), where k ≈ 1.3 to 1.5. As soon as N ⪆ 30, Shell sort will start clobbering Insertion sort. For N ≈ 1000, Shell sort is 10X faster than Insertion sort, which in turn is 6X faster than Bubble sort. Unfortunately Shell sort is not stable.
Comb sort has a similar O(N^k) runtime complexity as Shell sort. But it seems slower than Shell sort by a constant factor. Comb sort is also not stable. I cannot think of any reason to use Comb sort over Shell sort.
Quick sort is not much faster than Shell until about N ≈ 300. Above that, the O(N*log(N) of Quick sort wins over the O(N^k) of Shell sort. But Quick sort is not stable.
Merge sort is stable and runs in O(N*log(N)), but it consumes an extra O(N) of RAM, which may be impossible on a microcontroller. You may be forced back to Insertion sort for a stable sort.
Comment by thomasmg 5 days ago
You didn't mention heap sort. A simple implementation, which doesn't do any method calls just like shell sort (also next to the merge sort above) is about twice as complex than shell sort.
Comment by bxparks 4 days ago
I think I ignored Heap sort because it uses O(N) extra RAM, which is precious on a resource-constrained microcontroller.
Comment by thomasmg 4 days ago
Comment by JKCalhoun 5 days ago
Comment by somat 5 days ago
Comment by bxparks 5 days ago
Bubble sort doesn't click for me easily. I think it's because the terminating condition seems uglier than Selection sort or Insertion sort. I always have a little voice in the back of my mind, "Is this outer loop guaranteed to terminate?"
Comment by archargelod 5 days ago
I don't believe that insertion/selection sort is easier to grasp. Can you type it from memory, without looking it up? Here's bubble sort:
var swapped = true
while swapped:
swapped = false
for i in 0 .. list.len-2:
if list[i] > list[i+1]:
swap(list[i], list[i+1])
swapped = trueComment by bxparks 4 days ago
Selection sort was the first sorting algorithm that I ever created: Find the smallest element for slot #1. Find the next smallest for slot #2. And so on. I've recreated it from scratch many times. The double for-loop means that it is guaranteed to finish, and it is obviously O(N^2).
I did not learn about Bubble sort until my university class, where I thought, this is a terrible algorithm: It's not completely obvious that it will finish, and it's not obvious what the runtime complexity is. For example, if the inner loop used ">=" instead of ">", it would work for test data sets with unique elements, then hang forever with a real data set that contained duplicates.
Comment by minitech 5 days ago
Well, yeah, but that’s not a very useful heuristic for people who are already aware of the algorithms in question. If you ask people to come up with a way from scratch – probably without explicitly asking, in order to get better success, like by watching how they sort cards – I bet they won’t tend to come up with bubble sort. Maybe that says something about the relative intuitiveness of the approaches? Or not.
Comment by 3eb7988a1663 5 days ago
Comment by avmich 5 days ago
Comment by jeltz 4 days ago
for i in 1 .. list.len - 1:
j = i - 1
while j >= 0 and list[j] > list[j + 1]:
swap(list[j], list[j + 1])
j = j - 1Comment by hmng 5 days ago
For the curious, the ZX Spectrum microdrive listed files on the cartridges by order found on tape. I wanted to display it in alphabetical order like the "big" computers did.
Comment by JKCalhoun 4 days ago
Comment by ExtremisAndy 5 days ago
Comment by vbezhenar 5 days ago
It is your choice which career to pursue, but in my experience, absolute majority of programmers don't know algorithms and data structures outside of very shallow understanding required to pass some popular interview questions. May be you've put too high artificial barriers, which weren't necessary.
To be a professional software developer, you need to write code to solve real life tasks. These tasks mostly super-primitive in terms of algorithms. You just glue together libraries and write so-called "business-logic" in terms of incomprehensible tree of if-s which nobody truly understands. People love it and pay money for it.
Comment by melagonster 5 days ago
Should I be familiar with every step of Dijkstra’s search algorithm and remember the pseudocode at all times? Why don’t the textbooks explain why the algorithm is correct?
Comment by monadgonad 5 days ago
Somehow, I think you already know the answer to that is "no".
I've been working as a software engineer for over 8 years, with no computer science education. I don't know what Dijkstra's search algorithm is, let alone have memorised the pseudocode. I flicked through a book of data structures and algorithms once, but that was after I got my first software job. Unless you're only aiming for Google etc, you don't really need any of this.
Comment by chopin 5 days ago
Comment by minitech 5 days ago
The good ones do!
> Should I be familiar with every step of Dijkstra’s search algorithm and remember the pseudocode at all times?
If it’s the kind of thing you care to be familiar with, then being able to rederive every step of the usual-suspect algorithms is well within reach, yes. You don’t need to remember things in terms of pseudocode as such, more just broad concepts.
Comment by mamcx 5 days ago
I used to think alike (I'm +30 year programing) until I decide to do https://tablam.org, and making a "database" is the kind of project where all this stuff suddenly is practical and worthwhile.
Comment by tzs 5 days ago
Comment by JKCalhoun 4 days ago
Comment by tzs 4 days ago
for i = 0 to n-1
find an index j in A of the smallest member of A[i:n-1]
swap A[i] with A[j]
I think that selection sort is easy to understand and easier to see that it is correct because it can be separated into a two array version. Given input array A and an empty array B, do this: while A is not empty
find a smallest element of A
append that to B
The in place version earlier is essentially that, just storing B and A together in one array.That is something most non-programmers could easily come up with for physical sorting. For instance you have a row of books on a shelf that are in random order, and you want to move them to another shelf and have them sorted by author's last name.
1. Scan the first row to find the book that should come before all the rest on that row.
2. Move it to the end of the books on the second row.
3. Repeat until all the books have been moved.
Selection sort is in a sense just a computer implementation of a procedure that ordinary people have a good chance of coming up with when they need to sort physical items.
Selection sort performs better than bubble sort on random data. They are both O(n^2) but selection sort will perform fewer writes.
If you deal with data that is mostly already sorted though then bubble sort with early stopping is O(n) and wins.
With bubble sort I can't think of a two array version that makes it easier to understand. I also don't think many ordinary people would come up with bubble sort when sorting say their bookshelf.
There's also insertion sort. The two array version would be
while A is not empty
take the first element of A
insert that into B keeping B sorted
In bookshelf form1. Pick a book from the first row.
2. Find where that belongs in alphabetical order in the second row and put it there.
3. Repeat until you run out of books on the first row.
I think this is what most ordinary people who don't come up with selection sort would come up with.
The two array form can be converted to in place the same as selection sort.
Insertion sort is, like the others O(n^2). Like selection sort it is faster than bubble sort on random data. Unlike selection sort whose runtime is about the same no matter how the data is ordered, it is fast on almost sorted data.
Here's all three (bubble, selection, insertion) illustrated by folk dancers:
https://www.youtube.com/watch?v=Iv3vgjM8Pv4
Comment by anothernewdude 5 days ago
Comment by another_twist 5 days ago
Comment by strken 5 days ago
Comment by vlovich123 5 days ago
Comment by jandrewrogers 5 days ago
The idea was that the vast majority of arrays in a large set are not searched often enough to justify the cost of sorting them and sorting is an expensive operation if you are computing on a deadline. You also don't always know which ones will be heavily searched ahead of time. Using bubblesort, only the heavily accessed arrays end up sorted but as a side-effect of search rather than having separate heuristics to decide when/what to sort.
Comment by johnnyanmac 5 days ago
Also, general wisdom to be mindful of data sizes and cache coherency. O(NLogN) vs. O(N^2) doesn't mean much when you're only sorting a few dozen items. Meanwhile, O(N) space can have drastic performance hitches when reallocating memory.
Comment by nick__m 5 days ago
if you apply quicksort to 2^20 random integers, at some point you're sorting 2^17 8-integer subpartitions
why not use an 8 wide optimal sort network for those 8 integers?Comment by pieter3d 5 days ago
Comment by observationist 5 days ago
Comment by jaw0 5 days ago
and every new hire got taken to the whiteboard to learn about sort algorithm performance: bubblesort is O(n) in the best case.
and in our codebase, the data being sorted fit that best case (the data was already sorted or almost sorted).
Comment by avmich 5 days ago
Comment by Findecanor 5 days ago
Comment by sureglymop 5 days ago
I said sure, quicksort, mergesort or radixsort?
He just said "okay, let's skip to the next question". :)
Comment by arethuza 5 days ago
Comment by zitterbewegung 5 days ago
Comment by dspillett 5 days ago
Though in reality almost never: you almost always have a convenient built-in sort that is as quick & easy to use (likely quicker & easier), and in circumstances where the set is small enough for bubblesort to be just fine, the speed, memory use, or other properties of what-ever other sort your standard library uses aren't going to be a problem either.
As others have pointed out, sometimes it is useful for partial sorts due to the “always no less sorted than before at any point in the process (assuming no changes due to external influence)” property.
wrt:
> If you make each frame of the animation one pass of bubblesort, the particles will all move smoothly into the right positions. I couldn't find any examples in the wild,
There are hundreds of sort demos out there, both live running and on publicly hosted videos, that show the final positions by hue, getting this effect. Seems odd that they couldn't find a single one.
EDIT: actually, I can't find any of the rainbow based sort demos I was thinking of, a lot of promising links seem dead. I take back my little moan!
Comment by aappleby 5 days ago
Comment by another_twist 5 days ago
Comment by CyLith 5 days ago
Comment by ErroneousBosh 5 days ago
Comment by thomasmg 5 days ago
Comment by AnimalMuppet 5 days ago
Worse, big-O always hides a constant factor. What's bubblesort's constant? What's quicksort's? It wouldn't surprise me if, for small enough n (2 or 3, and maybe a bit higher), bubblesort is actually faster.
Note well: I have not actually benchmarked this.
Also note well: Determine what your n is; don't assume that it's either large or small.
Comment by caycep 5 days ago
Comment by sdsd 5 days ago
It was one of the many viral moments during Obama's original campaign where he seemed cool and in touch.
Comment by yunnpp 5 days ago
Comment by meindnoch 5 days ago
Comment by beeforpork 5 days ago
Comment by thomasmg 5 days ago
[1] https://github.com/thomasmueller/bau-lang/blob/main/src/test...
Comment by kazinator 5 days ago
https://en.wikipedia.org/wiki/Shellsort
Shellsort can be regarded as an improvement over either Bubble Sort or Insertion Sort.
Comment by 13415 5 days ago
Comment by opensourcemaxi 5 days ago
Comment by pilord314 5 days ago
You can also do something like a calendar queue with bubble sort for each bin.
Comment by lucraft 5 days ago
When I was playing The Farmer Was Replaced and needed to implement sorting, I just wrote a bubble sort. Worked first time.
Comment by LorenPechtel 5 days ago
And while I've never hit a case I would think it would have merit with data known to be pretty close to properly sorted.
Comment by pestatije 5 days ago
Comment by whateveracct 5 days ago
Comment by JSR_FDED 5 days ago
Comment by jhallenworld 5 days ago
Comment by bxparks 5 days ago
Comment by 6Roman6 5 days ago