Lecture. Sorting; Allocation
[comp1110-1O] - March 13, 2026
- Liam O'Connor
Lecture. Sorting; Allocation
[comp1110-1O]- March 13, 2026
- Liam O'Connor
1. Understanding reference types
[comp1110-1U] - Liam O'Connor, Fabian Muehlboeck
1. Understanding reference types
[comp1110-1U]- Liam O'Connor, Fabian Muehlboeck
Example 1.1. A puzzling question
[comp1110-1P] - Liam O'Connor, Fabian Muehlboeck
Example 1.1. A puzzling question
[comp1110-1P]- Liam O'Connor, Fabian Muehlboeck
Without running this program, try to deduce what it will output:
You will only get the answer correct if you understand what happens in Java when values are passed to functions.
Definition 1.2. Passing by value (or copy)
[comp1110-1R] - Liam O'Connor, Fabian Muehlboeck
Definition 1.2. Passing by value (or copy)
[comp1110-1R]- Liam O'Connor, Fabian Muehlboeck
A function's variables, including its parameters, are local to that invocation of the function. When we invoke a function, some memory is set aside for a frame: storage space for the local variables in the function. The values of the arguments given in the function invocation are copied into the function's frame. This is called pass by value. When the function returns, the frame is no longer needed and destroyed.
This is why the function fun3 has no effect on its arguments in example Example 1.1.
Definition 1.3. Value types and reference types
[comp1110-1Q] - Liam O'Connor
Definition 1.3. Value types and reference types
[comp1110-1Q]- Liam O'Connor
Variables of type int and char (for example) are called value types. This means that a variable declared of type, say int:
Will contain a value, a single integer. When left uninitialised as above, they are initialised to a default value of 0.
By contrast, array types like int[] and char[] are what's called reference types. This means that a variable declared of an
array type will not contain the array data itself, but instead will contain the location in memory where the data may be found. This location is called a reference or pointer.
Any type name that begins with a capital letter (e.g. String) is also a reference type. This is why Strings should not be compared with == — it would compare locations, not contents.
Definition 1.3 combined with Definition 1.2 tells us that when we call a function like fun1 or fun2 in Example 1.1, the array data itself is not copied into the function's frame, but instead just the
reference is. When fun1 or fun2 are called, the variable arr in their frame has the same value as the variable arr in the frame of main — they both point
to the same array. This means that when we call fun1, the contents of the array in main are observably changed, as the array indexing arr[0] follows the same pointer that is in main.
When we call fun2, however, nothing changes in the function main, because we don't follow the pointers, but instead just change the value of the local variable arr to point to a new array, then immediately discard it.
1.4. The Waterloo Java Visualizer
[comp1110-1S] - Liam O'Connor
1.4. The Waterloo Java Visualizer
[comp1110-1S]- Liam O'Connor
The Waterloo Java Visualizer is a great way to visualise what's going on in these examples. Here's a link to Example 1.1 being visualised in it. Click "forward" to step through the program's execution.
Note
that it doesn't support Java 25, so I had to include some cruft that Java 25 has since made obsolete like (a method-free) class, public static etc. We will learn about these things later in the course but they are not relevant for now.
1.5. Reference vs. Value Equality
[comp1110-1T] - Liam O'Connor, Fabian Muehlboeck
1.5. Reference vs. Value Equality
[comp1110-1T]- Liam O'Connor, Fabian Muehlboeck
The difference between value types and reference types explains the differences between == and other methods to decide equality.
For value types, == happens to capture regular equality - for example, there are no two int values that represent the number 32 but are somehow different.
On the other hand, for reference types, == describes reference equality, identifying whether two references point to the same object in memory.
Since there may be two different objects representing the same value, == is too strict in many cases.
We have seen this for String equality and Array equality.
It is the same way in general for objects of arbitrary classes, except that for those, by default, no other notion of equality comparison exists.
We'll see later how to define our own equality comparison.
Finally, Enums are a special case: they are a reference type, but with a guarantee that each case of a Enum refers to the same object in memory.
As such, comparing the references to Enum values using == is fine - as for ints, there are no two distinct values representing the same case.
2. Understanding sorting
[comp1110-1V] - Liam O'Connor
2. Understanding sorting
[comp1110-1V]- Liam O'Connor
Definition 2.1. A spec and a test suite for sorting
[comp1110-1W] - March 10, 2026
- Liam O'Connor
Definition 2.1. A spec and a test suite for sorting
[comp1110-1W]- March 10, 2026
- Liam O'Connor
Any in-place sorting algorithm, no matter how it is implemented, should satisfy the following spec:
Assuming we had such a function, we might test it (using proper array comparison) as follows:
Definition 2.2. Quadratic sorting methods
[comp1110-1X] - August 11, 2026
- Liam O'Connor, Fabian Muehlboeck
Definition 2.2. Quadratic sorting methods
[comp1110-1X]- August 11, 2026
- Liam O'Connor, Fabian Muehlboeck
We demonstrated two sorting algorithms in the lecture:
- Selection sort: We divide the array into an "unsorted zone" and a "sorted zone". The sorted zone begins empty at the start of the array, and the unsorted zone begins by occupying the whole array. Each loop iteration, we look through the unsorted zone, find the minimum, and swap it with the first element of the unsorted zone (right next to the sorted zone). This means that the sorted zone can be expanded by one element. Repeat until the unsorted zone is of size zero.
- Bubble sort: Here, the "sorted zone" grows from the end of the array rather than the beginning.
Loop through the unsorted zone comparing adjacent elements.
If they are not in order, swap them.
This will result in the highest element reaching the top.
This means we can increase the size of the sorted zone.
Repeat until all sorted.
If we go through the unsorted zone without doing any swaps, we can immediately stop — the array is sorted. This is called an early exit trick.
I briefly mentioned another one at the start of the workshop:
- Insertion sort: The most popular of these three, and somewhat similar to selection sort, in that the
sorted zone begins empty and grows from the left. Instead of finding the minimum, however, we take the first element from
the unsorted zone and remember it (call it
X) and shift everything greater thanXin the sorted zone to the right one spot. Then we placeXin the slot left over.
These algorithms are called "quadratic" because they take a quadratic amount of key operations (in terms of the size of the array), in this case comparisons and moves/swaps to perform.
While insertion sort is generally the most popular of the three, each of them have their own advantages, depending on your particular situation. On arrays:
- Selection sort minimizes the number of times you have to move an array element.
- Bubble sort only swaps adjacent elements and has an easy way to exit early on sorted arrays.
- Insertion sort can minimize the number of comparisons that you do (these can become expensive on more complex data types).
Which of these you actually get depends on the particulars of your implementation, and minor variations (say starting from the other direction) can make a huge difference for certain scenarios.
Example 2.3. Selection sort
[comp1110-1Y] - August 11, 2026
- Liam O'Connor, Fabian Muehlboeck
Example 2.3. Selection sort
[comp1110-1Y]- August 11, 2026
- Liam O'Connor, Fabian Muehlboeck
Example 2.4. Bubble sort
[comp1110-1Z] - August 11, 2026
- Liam O'Connor
Example 2.4. Bubble sort
[comp1110-1Z]- August 11, 2026
- Liam O'Connor
Bubble sort swaps a lot of elements, but the key idea is that once it finds the maximum element in the unsorted part of the array, it keeps "bubbling" it up further and further, until we reach the end of the unsorted part, where a sorted array of elements larger than the new element is waiting. In that sense, it works like selection sort (either one of them could also just work in the other direction), but with more elements being moved around. We include the "early exit" trick mentioned by Definition 2.2:
Definition 2.5. In-place
[comp1110-20]
Definition 2.5. In-place
[comp1110-20]An algorithm is in-place if only modifies existing structures, rather than create new ones. For example, for
sorting an in-place function returns void, as they don't produce a new array, they
just modify an old one. All our sorting algorithms in this section are in-place.