Sorting Algorithms
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:
- Choose a pivot, then put values smaller than it on the left and larger values on the right.
- 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
- Build a max heap from the array, where each parent is greater than its children.
- 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.