Skip to main content

Basic Sorting and Bubble Sort

Basic Sorting

When we have a few objects be it of any kind, and we want to sort them this means that we want to rearrange them somehow so that they follow some order, an order that we define.  We can take for example one of the fields, for example if we have sheep, and each sheep has a name, and we want to order the sheep by name then we could just take any sheep and first place the sheep named Avida, and then take the sheep named Guliantra and so on, lexicographically.

Respectively we could sort the sheep that we have by their age, and in this case Guliantra could end up before Avida.

In computer algorithms, sorting is the like the basic algorithms, and you will find that to solve many other problems you would start by first sorting and then progress to actually solve the problem.  So sorting could be the first step of many other problem solutions.

While there are a few types of sorting algorithms we have a few shared metrics to evaluate them all.  So when you refer me to a specific algorithm we could ask, is this sorting algorithm stable? Is it sorting in place? What is the average worst and best case running time of this sorting algorithm? Which type of data is this sorting algorithm best suited for, how much memory does this sorting algorithm require and does it need actually extra memory?

Let's go through these terms of stable, in place, running time, memory terms.

Stable Sort

Once you sort a few sheep let's say by year age, it might be the case that a few sheep have the same yearly age.

The question then is this, if the sheep are all lined up but not sorted by yearly age, and you sort them out by their yearly ages, if two sheep have the same age would they have different relative order after the sorting?

Note that we didn't say absolute order, because it might be well the case that the two oldest sheep with the same age are lined up at first on the beginning of the row, but at the end of the sort you line them up at the end of the row.

The question is just if when you sort and line up these oldest sheets at the end of the line if they preserve their original ordering, if they always do when sorted by your sorting algorithm, then we say that your sorting algorithm is relative order preserving for equal items or in other words a stable sort.

Stable sorts include: Merge sort, insertion sort, radix sort, tim sort, bubble sort.
Unstable sorts include: Heap sort, quick sort.

In Place

When we ask if a sorting algorithm is in place or not we ask about how much extra memory it's using.  As long as it's using a constant amount of memory relative to the list that you sort then we say it's in place.  You can use additional memory for your sorting, that is all fine, but the question is whether the extra memory is of constant space meaning, it's not growing relatively to the number of items you sort.

It does not matter the relation between the additional memory use to the number of items in list, any such relation means that it's not in place.  In order for a sorting algorithm to be in place it must use O(1) extra amount of memory, meaning no extra relation to the original items that you sort, you can sort as many items as you wish your sorting algorithm must only use extract constant amount of memory in order to be called in place.

Bubble Sort

Bubble sort is a stable sort, it's also in place, it's best time complexity is O(n), it's average time complexity is O(n^2), it's worst time complexity is O(n^2), and it's space complexity is O(1).

In bubble sort we compare each successive part of elements in some given input list, and we invert each such pare if they are not in order.

After we finish one iteration of scanning the whole list, comparing each two items and replace each such two if they are inverted then if we started this comparison from the beginning of the list then this would mean we bubble up the largest element to the n-1 place the end of the list.

Bubble sort is also known as sinking sort because it's repeatedly comparing each two items and swaps if they are at the wrong order, so the items are like sinking to one end of the list.

After one iteration of comparing all the pairs you are sure to have one item sorted, the largest item if you start from the beginning of the list, and after two such iterations of the whole array you have the two largest items ordered at the end of the list.

We said that the best running time of bubble sort is O(n) that is because if we scan the list once, and we see we need not swap any two items we can shortcut and end the sorting here, as we saw the list is sorted already.


Comments

Popular posts from this blog

Functional Programming in Scala for Working Class OOP Java Programmers - Part 1

Introduction Have you ever been to a scala conf and told yourself "I have no idea what this guy talks about?" did you look nervously around and see all people smiling saying "yeah that's obvious " only to get you even more nervous? . If so this post is for you, otherwise just skip it, you already know fp in scala ;) This post is optimistic, although I'm going to say functional programming in scala is not easy, our target is to understand it, so bare with me. Let's face the truth functional programmin in scala is difficult if is difficult if you are just another working class programmer coming mainly from java background. If you came from haskell background then hell it's easy. If you come from heavy math background then hell yes it's easy. But if you are a standard working class java backend engineer with previous OOP design background then hell yeah it's difficult. Scala and Design Patterns An interesting point of view on scala, is

Alternatives to Using UUIDs

  Alternatives to Using UUIDs UUIDs are valuable for several reasons: Global Uniqueness : UUIDs are designed to be globally unique across systems, ensuring that no two identifiers collide unintentionally. This property is crucial for distributed systems, databases, and scenarios where data needs to be uniquely identified regardless of location or time. Standardization : UUIDs adhere to well-defined formats (such as UUIDv4) and are widely supported by various programming languages and platforms. This consistency simplifies interoperability and data exchange. High Collision Resistance : The probability of generating duplicate UUIDs is extremely low due to the combination of timestamp, random bits, and other factors. This collision resistance is essential for avoiding data corruption. However, there are situations where UUIDs may not be the optimal choice: Length and Readability : UUIDs are lengthy (typically 36 characters in their canonical form) and may not be human-readable. In URLs,

Bellman Ford Graph Algorithm

The Shortest path algorithms so you go to google maps and you want to find the shortest path from one city to another.  Two algorithms can help you, they both calculate the shortest distance from a source node into all other nodes, one node can handle negative weights with cycles and another cannot, Dijkstra cannot and bellman ford can. One is Dijkstra if you run the Dijkstra algorithm on this map its input would be a single source node and its output would be the path to all other vertices.  However, there is a caveat if Elon mask comes and with some magic creates a black hole loop which makes one of the edges negative weight then the Dijkstra algorithm would fail to give you the answer. This is where bellman Ford algorithm comes into place, it's like the Dijkstra algorithm only it knows to handle well negative weight in edges. Dijkstra has an issue handling negative weights and cycles Bellman's ford algorithm target is to find the shortest path from a single node in a graph t