Sorting Algorithms

Liao Jiayi Liao Jiayi #Algorithm#Programming fundamentals

Sorting is fundamental, but different algorithms embody different ideas worth studying. To reinforce my understanding, I am implementing the basic sorting algorithms by hand.

Translated from Chinese with AI · Read the original

Sorting is fundamental, but different algorithms embody different ideas worth studying. To reinforce my understanding, I am implementing the basic sorting algorithms by hand.

Quicksort

Given an array:

  1. Choose a pivot, then put values smaller than it on the left and larger values on the right.
  2. Repeat step 1 on the subarrays to the left and right of the pivot.
def quickSort(arr: Array[Int], begin: Int, end: Int): Unit = {
if (end > begin) {
var (i, j) = (begin, end)
val pivot = arr(i)
while (i < j) {
while (j > i && arr(j) > pivot) {
j -= 1
}
if (j > i) {
swap(arr, i, j)
}
while (i < j && arr(i) < pivot) {
i += 1
}
if (i < j) {
swap(arr, i, j)
}
}
quickSort(arr, begin, i-1)
quickSort(arr, i+1, end)
}
}

Insertion Sort:

def insertSort(arr: Array[Int]): Unit = {
arr.indices.foreach(i => {
val v = arr(i)
(i to 1 by -1).foreach(j => {
if (arr(j-1) > arr(j)) {
val temp = arr(j)
arr.update(j, arr(j-1))
arr.update(j-1, temp)
}
})
})
}

Bubble Sort

Traverse all elements and keep swapping them. n * n: a rather silly algorithm.

def bubbleSort(arr: Array[Int]): Unit = {
arr.indices.foreach(i => {
(0 until arr.length - 1).foreach(j => {
if (arr(j) > arr(j+1)) {
swap(arr, j, j+1)
}
})
})
}

Selection Sort

Too silly a sorting algorithm to bother writing…

Merge Sort

Merge two sorted arrays: sorted array = merge(sorted array(0 -> mid), sorted array(mid+1 -> N)), giving a recursive procedure.

def mergeSort(arr: Array[Int], begin: Int, end: Int): Array[Int] = {
if (begin == end) Array(arr(begin))
else {
val mid = (begin + end) / 2
merge(mergeSort(arr, begin, mid), mergeSort(arr, mid+1, end))
}
}
def merge(arr1: Array[Int], arr2: Array[Int]): Array[Int] = {
var (i, j) = (0, 0)
val newArr = mutable.ArrayBuffer[Int]()
while (i < arr1.length || j < arr2.length) {
if (i >= arr1.length) {
newArr.append(arr2(j))
j +=1
} else if (j >= arr2.length) {
newArr.append(arr1(i))
i += 1
} else if (arr1(i) <= arr2(j)) {
newArr.append(arr1(i))
i += 1
} else if (arr1(i) > arr2(j)) {
newArr.append(arr2(j))
j += 1
}
}
newArr.toArray
}

Heap Sort

  1. Build a max heap from the array, where each parent is greater than its children.
  2. Move the first value of the max heap to the end, rebuild the heap from the remaining values, and repeat.
def heapsort(arr: Array[Int]): Unit = {
// 构建大顶堆
(0 to arr.length / 2).foreach(i => {
adjustHeap(arr, i, arr.length)
})
// remove first
(arr.length to 1 by -1).foreach(i => {
swap(arr, 0, i-1)
adjustHeap(arr, 0, i-1)
})
}
def adjustHeap(arr: Array[Int], idx: Int, length: Int): Unit = {
(0 to length / 2).foreach(i => {
var maxIdx = i
if (i * 2+1 < length && arr(i*2+1) > arr(i)) {
maxIdx = i * 2+1
}
if (i * 2 + 2 < length && arr(i*2+2) > arr(maxIdx)) {
maxIdx = i * 2 + 2
}
swap(arr, i, maxIdx)
})
}

Counting Sort

Trade space for time: exploit a bounded set of possible values to place elements directly into their corresponding positions.

Bucket Sort

Use a partition function to distribute the dataset into buckets, then sort the data within each bucket.