Algorithm 1: Ten common sorting algorithms (implemented in Go language)

Top ten common sorting algorithms (implemented in Go language)

Bubble Sort
Selection Sort
Insertion Sort
Shell Sort
Merge Sort
Quick Sort
Heap Sort
Counting Sort
Bucket Sort
Radix Sort

go language implementation

package main

import "fmt"

// 冒泡排序
func BubbleSort(arr []int) {
    
    
	n := len(arr)
	for i := 0; i < n-1; i++ {
    
    
		for j := 0; j < n-i-1; j++ {
    
    
			if arr[j] > arr[j+1] {
    
    
				arr[j], arr[j+1] = arr[j+1], arr[j]
			}
		}
	}
}

// 选择排序
func SelectionSort(arr []int) {
    
    
	n := len(arr)
	for i := 0; i < n-1; i++ {
    
    
		minIndex := i
		for j := i + 1; j < n; j++ {
    
    
			if arr[j] < arr[minIndex] {
    
    
				minIndex = j
			}
		}
		arr[i], arr[minIndex] = arr[minIndex], arr[i]
	}
}

// 插入排序
func InsertionSort(arr []int) {
    
    
	n := len(arr)
	for i := 1; i < n; i++ {
    
    
		key := arr[i]
		j := i - 1
		for j >= 0 && arr[j] > key {
    
    
			arr[j+1] = arr[j]
			j--
		}
		arr[j+1] = key
	}
}

// 希尔排序
func ShellSort(arr []int) {
    
    
	n := len(arr)
	gap := n / 2
	for gap > 0 {
    
    
		for i := gap; i < n; i++ {
    
    
			j := i
			for j-gap >= 0 && arr[j-gap] > arr[j] {
    
    
				arr[j-gap], arr[j] = arr[j], arr[j-gap]
				j -= gap
			}
		}
		gap /= 2
	}
}

// 归并排序
func MergeSort(arr []int) []int {
    
    
	if len(arr) <= 1 {
    
    
		return arr
	}
	mid := len(arr) / 2
	left := MergeSort(arr[:mid])
	right := MergeSort(arr[mid:])
	return merge(left, right)
}

func merge(left, right []int) []int {
    
    
	result := make([]int, 0)
	i, j := 0, 0
	for i < len(left) && j < len(right) {
    
    
		if left[i] < right[j] {
    
    
			result = append(result, left[i])
			i++
		} else {
    
    
			result = append(result, right[j])
			j++
		}
	}
	result = append(result, left[i:]...)
	result = append(result, right[j:]...)
	return result
}

// 快速排序
func QuickSort(arr []int) {
    
    
	quickSort(arr, 0, len(arr)-1)
}

func quickSort(arr []int, left, right int) {
    
    
	if left < right {
    
    
		pivot := partition(arr, left, right)
		quickSort(arr, left, pivot-1)
		quickSort(arr, pivot+1, right)
	}
}

func partition(arr []int, left, right int) int {
    
    
	pivot := arr[right]
	i := left - 1
	for j := left; j < right; j++ {
    
    
		if arr[j] < pivot {
    
    
			i++
			arr[i], arr[j] = arr[j], arr[i]
		}
	}
	arr[i+1], arr[right] = arr[right], arr[i+1]
	return i + 1
}

// 堆排序
func HeapSort(arr []int) {
    
    
	n := len(arr)
	for i := n/2 - 1; i >= 0; i-- {
    
    
		heapify(arr, n, i)
	}
	for i := n - 1; i >= 0; i-- {
    
    
		arr[0], arr[i] = arr[i], arr[0]
		heapify(arr, i, 0)
	}
}

func heapify(arr []int, n, i int) {
    
    
	largest := i
	left := 2*i + 1
	right := 2*i + 2
	if left < n && arr[left] > arr[largest] {
    
    
		largest = left
	}
	if right < n && arr[right] > arr[largest] {
    
    
		largest = right
	}
	if largest != i {
    
    
		arr[i], arr[largest] = arr[largest], arr[i]
		heapify(arr, n, largest)
	}
}

// 计数排序
func CountingSort(arr []int) {
    
    
	n := len(arr)
	if n <= 1 {
    
    
		return
	}
	maxVal := arr[0]
	for i := 1; i < n; i++ {
    
    
		if arr[i] > maxVal {
    
    
			maxVal = arr[i]
		}
	}
	count := make([]int, maxVal+1)
	for i := 0; i < n; i++ {
    
    
		count[arr[i]]++
	}
	for i, j := 0, 0; i <= maxVal; i++ {
    
    
		for count[i] > 0 {
    
    
			arr[j] = i
			j++
			count[i]--
		}
	}
}

// 桶排序
func BucketSort(arr []int) {
    
    
	n := len(arr)
	if n <= 1 {
    
    
		return
	}
	maxVal := arr[0]
	minVal := arr[0]
	for i := 1; i < n; i++ {
    
    
		if arr[i] > maxVal {
    
    
			maxVal = arr[i]
		}
		if arr[i] < minVal {
    
    
			minVal = arr[i]
		}
	}
	bucketSize := 10
	bucketCount := (maxVal-minVal)/bucketSize + 1
	buckets := make([][]int, bucketCount)
	for i := 0; i < bucketCount; i++ {
    
    
		buckets[i] = make([]int, 0)
	}
	for i := 0; i < n; i++ {
    
    
		index := (arr[i] - minVal) / bucketSize
		buckets[index] = append(buckets[index], arr[i])
	}
	k := 0
	for i := 0; i < bucketCount; i++ {
    
    
		if len(buckets[i]) > 0 {
    
    
			InsertionSort(buckets[i])
			copy(arr[k:], buckets[i])
			k += len(buckets[i])
		}
	}
}

// 基数排序
func RadixSort(arr []int) {
    
    
	n := len(arr)
	if n <= 1 {
    
    
		return
	}
	maxVal := arr[0]
	for i := 1; i < n; i++ {
    
    
		if arr[i] > maxVal {
    
    
			maxVal = arr[i]
		}
	}
	exp := 1
	for maxVal/exp > 0 {
    
    
		countingSortForRadix(arr, exp)
		exp *= 10
	}
}

func countingSortForRadix(arr []int, exp int) {
    
    
	n := len(arr)
	count := make([]int, 10)
	output := make([]int, n)
	for i := 0; i < n; i++ {
    
    
		index := (arr[i] / exp) % 10
		count[index]++
	}
	for i := 1; i < 10; i++ {
    
    
		count[i] += count[i-1]
	}
	for i := n - 1; i >= 0; i-- {
    
    
		index := (arr[i] / exp) % 10
		output[count[index]-1] = arr[i]
		count[index]--
	}
	for i := 0; i < n; i++ {
    
    
		arr[i] = output[i]
	}
}

func main() {
    
    
	arr1 := []int{
    
    1, 3, 2, 5, 4, 7, 6, 9, 8}
	arr2 := []int{
    
    1, 3, 2, 5, 4, 7, 6, 9, 8}
	arr3 := []int{
    
    1, 3, 2, 5, 4, 7, 6, 9, 8}
	arr4 := []int{
    
    1, 3, 2, 5, 4, 7, 6, 9, 8}
	arr5 := []int{
    
    1, 3, 2, 5, 4, 7, 6, 9, 8}
	arr6 := []int{
    
    1, 3, 2, 5, 4, 7, 6, 9, 8}
	arr7 := []int{
    
    1, 3, 2, 5, 4, 7, 6, 9, 8}
	arr8 := []int{
    
    1, 3, 2, 5, 4, 7, 6, 9, 8}
	arr9 := []int{
    
    1, 3, 2, 5, 4, 7, 6, 9, 8}
	arr10 := []int{
    
    1, 3, 2, 5, 4, 7, 6, 9, 8}
	BubbleSort(arr1)
	fmt.Printf("arr1: %v\n", arr1)

	SelectionSort(arr2)
	fmt.Printf("arr2: %v\n", arr2)

	InsertionSort(arr3)
	fmt.Printf("arr3: %v\n", arr3)

	ShellSort(arr4)
	fmt.Printf("arr4: %v\n", arr4)

	arr5 = MergeSort(arr5)
	fmt.Printf("arr5: %v\n", arr5)

	QuickSort(arr6)
	fmt.Printf("arr6: %v\n", arr6)

	HeapSort(arr7)
	fmt.Printf("arr7: %v\n", arr7)

	CountingSort(arr8)
	fmt.Printf("arr8: %v\n", arr8)

	BucketSort(arr9)
	fmt.Printf("arr9: %v\n", arr9)

	RadixSort(arr10)
	fmt.Printf("arr10: %v\n", arr10)
}

Output result:

$ go run main.go
arr1: [1 2 3 4 5 6 7 8 9]
arr2: [1 2 3 4 5 6 7 8 9]
arr3: [1 2 3 4 5 6 7 8 9]
arr4: [1 2 3 4 5 6 7 8 9]
arr5: [1 2 3 4 5 6 7 8 9]
arr6: [1 2 3 4 5 6 7 8 9]
arr7: [1 2 3 4 5 6 7 8 9]
arr8: [1 2 3 4 5 6 7 8 9]
arr9: [1 2 3 4 5 6 7 8 9]
arr10: [1 2 3 4 5 6 7 8 9]

A brief explanation of the principle, execution process, complexity and time-consuming of the sorting algorithm

Bubble sort:
Compare adjacent elements and swap their positions if the previous one is greater than the next one. Repeat this process until the entire sequence is in order.
The time complexity is O(n^2) and the space complexity is O(1). In the worst case, n(n-1)/2 comparison and exchange operations are required.

Selection sort:
Select the smallest element from the unsorted sequence each time and put it at the end of the sorted sequence.
The time complexity is O(n^2) and the space complexity is O(1). In the worst case, n(n-1)/2 comparisons and n-1 swap operations are required.

Insertion sort:
Insert an element into the appropriate position of the sorted sequence so that the sequence after insertion is still in order.
The time complexity is O(n^2) and the space complexity is O(1). In the worst case, n(n-1)/2 comparisons and n(n-1)/2 move operations are required.

Hill sorting:
Divide the sequence into several subsequences, perform insertion sorting on each subsequence, then gradually reduce the length of the subsequence, and finally perform insertion sorting on the entire sequence.
The time complexity is O(nlogn)~O(n^2), and the space complexity is O(1).

Merge sort:
Divide the sequence into several subsequences, sort each subsequence, and then merge the sorted subsequences into an ordered sequence. The time complexity is O(nlogn) and the space complexity is O(n).

Quick sort:
Select a benchmark element, divide the sequence into two subsequences, put the ones smaller than the benchmark element on the left, and put the ones larger than the benchmark element on the right, and then quickly sort the left and right subsequences recursively.
The time complexity is O(nlogn), and the space complexity is O(logn)~O(n).

Heap sort:
Build the sequence into a heap, then take out the top elements of the heap and put them at the end of the sorted sequence.
The time complexity is O(nlogn) and the space complexity is O(1).

Counting sort:
Count the number of occurrences of each element in the sequence, and then reconstruct the sequence based on the number of occurrences of the element.
The time complexity is O(n+k) and the space complexity is O(k), where k is the value range of the elements in the sequence.

Bucket sorting:
Divide the sequence into several buckets, sort each bucket, and then put the elements in all buckets together in order.
The time complexity is O(n) and the space complexity is O(n).

Radix sort:
Sort the sequence according to the number of digits, from low to high.
The time complexity is O(d(n+r)), and the space complexity is O(n+r), where d is the number of digits in the maximum number and r is the base.

Guess you like

Origin blog.csdn.net/weixin_42492572/article/details/132016347