27  Introduction to Sorting

27.1 Understanding the Sorting Problem

Sorting is an essential problem in computer science and software engineering. Simply put, sorting is the task of rearranging a set of items, such as an array, in a specific order. For instance, an array of integers might be sorted in ascending or descending order based on their numeric value.

One might wonder why sorting is so ubiquitous in the field of software engineering. The answer lies in the multitude of applications that it has. Sorting allows for more efficient searching, data compression, and organization. It is a crucial step in numerous algorithms and computational tasks. The efficiency of a sorting algorithm can significantly affect the performance of these applications.

27.2 Developing a Sorting Algorithm from Scratch

One might find the task of developing a sorting algorithm from scratch quite daunting. Sorting algorithms, like many computational problems, have an abstract and often complex nature that can make it difficult to understand, let alone create. If shown the solution, one might understand how it works and even memorize it, but the thought process behind creating such a solution can be elusive.

A common approach to overcoming such challenges is to simplify the problem. By breaking down a complex problem into simpler subproblems, we can gain insights into the problem’s structure and ultimately develop a solution. This approach will be demonstrated as we develop a sorting algorithm.

27.3 Starting Simple: Sorting an Array of Size 1

The simplest possible sorting problem involves an array of size one. But, of course, this array is already sorted as it only contains a single element. Thus, we need to do nothing to sort this array. Here’s how this can be implemented in Java:

public static void sort1(int[] arr) {
  // do nothing
}

27.4 Sorting an Array of Size 2

What about an array of size two? In this case, we simply need to compare the two elements and swap them if they are out of order:

public static void sort2(int[] arr) {
    if (arr[0] > arr[1]) {
      int temp = arr[0];
      arr[0] = arr[1];
      arr[1] = temp;
    }
}

27.5 Expanding the Problem: Sorting an Array of Size 3

When sorting an array of size three, we perform similar steps as we did for the array of size two. First, we compare and potentially swap the first two numbers. Then, we do the same for the second and third numbers. Finally, we compare the first two numbers once again:

public static void sort3(int[] arr) {
    if (arr[0] > arr[1]) {
      int temp = arr[0];
      arr[0] = arr[1];
      arr[1] = temp;
    }
    if (arr[1] > arr[2]) {
      int temp = arr[1];
      arr[1] = arr[2];
      arr[2] = temp;
    }
    if (arr[0] > arr[1]) {
      int temp = arr[0];
      arr[0] = arr[1];
      arr[1] = temp;
    }
}

By following this process, we ensure that the array is sorted, regardless of the initial order of the elements.

27.6 Scaling Up: Sorting an Array of Size 4

We can extend the same approach to sort an array of size four. However, notice that once we have the largest number at the last position, the problem

reduces to sorting an array of size three. This realization will be crucial as we move forward.

public static void sort4(int[] arr) {
    for(int i = 0; i < 3; i++) {
      if (arr[i] > arr[i+1]) {
        int temp = arr[i];
        arr[i] = arr[i+1];
        arr[i+1] = temp;
      }
    }
    sort3(arr);
}

27.7 Recognizing the Pattern

As we incrementally solve larger versions of our sorting problem, we start to notice a pattern. For every array size, we first ensure the largest number ends up at the end of the array. Then, we apply the same sorting logic to the remaining elements in the array.

For instance, when sorting an array of size 5, we first find and move the largest number to the end of the array, then apply the sorting process for an array of size 4 to the remaining numbers:

public static void sort5(int[] arr) {
  for(int i = 0; i < 4; i++) {
    if (arr[i] > arr[i+1]) {
      int temp = arr[i];
      arr[i] = arr[i+1];
      arr[i+1] = temp;
    }
  }
  sort4(arr);
}

27.8 Generalizing the Algorithm

This pattern suggests a way to generalize our algorithm to sort an array of any size. For an array of size n, we first ensure the largest number ends up at the end, then recursively apply the same process to the remaining n-1 elements. By repeatedly applying this process, we ensure that the entire array ends up sorted.

public static void sort(int[] arr) {
  for(int i = arr.length - 1; i > 0; i--) {
    for(int j = 0; j < i; j++) {
      if (arr[j] > arr[j+1]) {
        int temp = arr[j];
        arr[j] = arr[j+1];
        arr[j+1] = temp;
      }
    }
  }
}

This algorithm, known as Bubble Sort, represents a simple yet effective solution to the sorting problem. It demonstrates how complex problems can often be broken down into simpler subproblems, providing a valuable lesson for problem-solving in computer science and beyond.