mirror of
https://github.com/krahets/hello-algo.git
synced 2026-08-14 04:30:58 +00:00
Add ru version (#1865)
* Add Russian docs site baseline * Add Russian localized codebase * Polish Russian code wording * Update ru code translation. * Update code translation and chapter covers. * Fix pythontutor extraction. * Add README and landing page. * placeholder of profiles * Use figures of English version * Remove chapter paperbook
This commit is contained in:
@@ -0,0 +1,38 @@
|
||||
// File: bubble_sort.go
|
||||
// Created Time: 2022-12-06
|
||||
// Author: Slone123c (274325721@qq.com)
|
||||
|
||||
package chapter_sorting
|
||||
|
||||
/* Пузырьковая сортировка */
|
||||
func bubbleSort(nums []int) {
|
||||
// Внешний цикл: неотсортированный диапазон [0, i]
|
||||
for i := len(nums) - 1; i > 0; i-- {
|
||||
// Внутренний цикл: переместить максимальный элемент неотсортированного диапазона [0, i] в его правый конец
|
||||
for j := 0; j < i; j++ {
|
||||
if nums[j] > nums[j+1] {
|
||||
// Поменять местами nums[j] и nums[j + 1]
|
||||
nums[j], nums[j+1] = nums[j+1], nums[j]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Пузырьковая сортировка (оптимизация флагом) */
|
||||
func bubbleSortWithFlag(nums []int) {
|
||||
// Внешний цикл: неотсортированный диапазон [0, i]
|
||||
for i := len(nums) - 1; i > 0; i-- {
|
||||
flag := false // Инициализировать флаг
|
||||
// Внутренний цикл: переместить максимальный элемент неотсортированного диапазона [0, i] в его правый конец
|
||||
for j := 0; j < i; j++ {
|
||||
if nums[j] > nums[j+1] {
|
||||
// Поменять местами nums[j] и nums[j + 1]
|
||||
nums[j], nums[j+1] = nums[j+1], nums[j]
|
||||
flag = true // Записать обмен элементов
|
||||
}
|
||||
}
|
||||
if flag == false { // На этой итерации «всплытия» не было ни одного обмена, сразу выйти
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
// File: bubble_sort_test.go
|
||||
// Created Time: 2022-12-06
|
||||
// Author: Slone123c (274325721@qq.com)
|
||||
|
||||
package chapter_sorting
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestBubbleSort(t *testing.T) {
|
||||
nums := []int{4, 1, 3, 1, 5, 2}
|
||||
bubbleSort(nums)
|
||||
fmt.Println("После пузырьковой сортировки nums =", nums)
|
||||
|
||||
nums1 := []int{4, 1, 3, 1, 5, 2}
|
||||
bubbleSortWithFlag(nums1)
|
||||
fmt.Println("После пузырьковой сортировки nums1 =", nums1)
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
// File: bucket_sort.go
|
||||
// Created Time: 2023-03-27
|
||||
// Author: Reanon (793584285@qq.com)
|
||||
|
||||
package chapter_sorting
|
||||
|
||||
import "sort"
|
||||
|
||||
/* Сортировка корзинами */
|
||||
func bucketSort(nums []float64) {
|
||||
// Инициализировать k = n/2 корзин, предполагая распределение 2 элементов в каждую корзину
|
||||
k := len(nums) / 2
|
||||
buckets := make([][]float64, k)
|
||||
for i := 0; i < k; i++ {
|
||||
buckets[i] = make([]float64, 0)
|
||||
}
|
||||
// 1. Распределить элементы массива по корзинам
|
||||
for _, num := range nums {
|
||||
// Входные данные лежат в диапазоне [0, 1); использовать num * k для отображения в диапазон индексов [0, k-1]
|
||||
i := int(num * float64(k))
|
||||
// Добавить num в корзину i
|
||||
buckets[i] = append(buckets[i], num)
|
||||
}
|
||||
// 2. Выполнить сортировку внутри каждой корзины
|
||||
for i := 0; i < k; i++ {
|
||||
// Использовать встроенную функцию сортировки среза; ее также можно заменить другим алгоритмом сортировки
|
||||
sort.Float64s(buckets[i])
|
||||
}
|
||||
// 3. Обойти корзины и объединить результаты
|
||||
i := 0
|
||||
for _, bucket := range buckets {
|
||||
for _, num := range bucket {
|
||||
nums[i] = num
|
||||
i++
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
// File: bucket_sort_test.go
|
||||
// Created Time: 2023-03-27
|
||||
// Author: Reanon (793584285@qq.com)
|
||||
|
||||
package chapter_sorting
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestBucketSort(t *testing.T) {
|
||||
// Пусть входные данные — числа с плавающей точкой из диапазона [0, 1)
|
||||
nums := []float64{0.49, 0.96, 0.82, 0.09, 0.57, 0.43, 0.91, 0.75, 0.15, 0.37}
|
||||
bucketSort(nums)
|
||||
fmt.Println("После сортировки корзинами nums =", nums)
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
// File: counting_sort.go
|
||||
// Created Time: 2023-03-20
|
||||
// Author: Reanon (793584285@qq.com)
|
||||
|
||||
package chapter_sorting
|
||||
|
||||
type CountingSort struct{}
|
||||
|
||||
/* Сортировка подсчетом */
|
||||
// Простая реализация, не подходит для сортировки объектов
|
||||
func countingSortNaive(nums []int) {
|
||||
// 1. Найти максимальный элемент массива m
|
||||
m := 0
|
||||
for _, num := range nums {
|
||||
if num > m {
|
||||
m = num
|
||||
}
|
||||
}
|
||||
// 2. Подсчитать число появлений каждой цифры
|
||||
// counter[num] обозначает число появлений num
|
||||
counter := make([]int, m+1)
|
||||
for _, num := range nums {
|
||||
counter[num]++
|
||||
}
|
||||
// 3. Обойти counter и заполнить исходный массив nums элементами
|
||||
for i, num := 0, 0; num < m+1; num++ {
|
||||
for j := 0; j < counter[num]; j++ {
|
||||
nums[i] = num
|
||||
i++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Сортировка подсчетом */
|
||||
// Полная реализация, позволяет сортировать объекты и является стабильной сортировкой
|
||||
func countingSort(nums []int) {
|
||||
// 1. Найти максимальный элемент массива m
|
||||
m := 0
|
||||
for _, num := range nums {
|
||||
if num > m {
|
||||
m = num
|
||||
}
|
||||
}
|
||||
// 2. Подсчитать число появлений каждой цифры
|
||||
// counter[num] обозначает число появлений num
|
||||
counter := make([]int, m+1)
|
||||
for _, num := range nums {
|
||||
counter[num]++
|
||||
}
|
||||
// 3. Вычислить префиксные суммы counter и преобразовать «число появлений» в «конечный индекс»
|
||||
// То есть counter[num]-1 — это индекс последнего появления num в res
|
||||
for i := 0; i < m; i++ {
|
||||
counter[i+1] += counter[i]
|
||||
}
|
||||
// 4. Обойти nums в обратном порядке и поместить элементы в результирующий массив res
|
||||
// Инициализировать массив res для хранения результата
|
||||
n := len(nums)
|
||||
res := make([]int, n)
|
||||
for i := n - 1; i >= 0; i-- {
|
||||
num := nums[i]
|
||||
// Поместить num по соответствующему индексу
|
||||
res[counter[num]-1] = num
|
||||
// Уменьшить префиксную сумму на 1, чтобы получить индекс следующего размещения num
|
||||
counter[num]--
|
||||
}
|
||||
// Перезаписать исходный массив nums массивом результата res
|
||||
copy(nums, res)
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
// File: counting_sort_test.go
|
||||
// Created Time: 2023-03-20
|
||||
// Author: Reanon (793584285@qq.com)
|
||||
|
||||
package chapter_sorting
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestCountingSort(t *testing.T) {
|
||||
nums := []int{1, 0, 1, 2, 0, 4, 0, 2, 2, 4}
|
||||
countingSortNaive(nums)
|
||||
fmt.Println("После сортировки подсчетом (объекты не поддерживаются) nums =", nums)
|
||||
|
||||
nums1 := []int{1, 0, 1, 2, 0, 4, 0, 2, 2, 4}
|
||||
countingSort(nums1)
|
||||
fmt.Println("После сортировки подсчетом nums1 =", nums1)
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
// File: heap_sort.go
|
||||
// Created Time: 2023-05-29
|
||||
// Author: Reanon (793584285@qq.com)
|
||||
|
||||
package chapter_sorting
|
||||
|
||||
/* Длина кучи равна n; начиная с узла i, выполнить просеивание сверху вниз */
|
||||
func siftDown(nums *[]int, n, i int) {
|
||||
for true {
|
||||
// Определить узел с максимальным значением среди i, l и r и обозначить его как ma
|
||||
l := 2*i + 1
|
||||
r := 2*i + 2
|
||||
ma := i
|
||||
if l < n && (*nums)[l] > (*nums)[ma] {
|
||||
ma = l
|
||||
}
|
||||
if r < n && (*nums)[r] > (*nums)[ma] {
|
||||
ma = r
|
||||
}
|
||||
// Если узел i уже максимален или индексы l и r вне границ, дальнейшее просеивание не требуется, выйти
|
||||
if ma == i {
|
||||
break
|
||||
}
|
||||
// Поменять два узла местами
|
||||
(*nums)[i], (*nums)[ma] = (*nums)[ma], (*nums)[i]
|
||||
// Циклическое просеивание вниз
|
||||
i = ma
|
||||
}
|
||||
}
|
||||
|
||||
/* Сортировка кучей */
|
||||
func heapSort(nums *[]int) {
|
||||
// Построение кучи: выполнить heapify для всех узлов, кроме листовых
|
||||
for i := len(*nums)/2 - 1; i >= 0; i-- {
|
||||
siftDown(nums, len(*nums), i)
|
||||
}
|
||||
// Извлекать максимальный элемент из кучи в течение n-1 итераций
|
||||
for i := len(*nums) - 1; i > 0; i-- {
|
||||
// Поменять корневой узел с самым правым листом местами (поменять первый и последний элементы)
|
||||
(*nums)[0], (*nums)[i] = (*nums)[i], (*nums)[0]
|
||||
// Начиная с корневого узла, выполнить просеивание сверху вниз
|
||||
siftDown(nums, i, 0)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
// File: heap_sort_test.go
|
||||
// Created Time: 2023-05-29
|
||||
// Author: Reanon (793584285@qq.com)
|
||||
|
||||
package chapter_sorting
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestHeapSort(t *testing.T) {
|
||||
nums := []int{4, 1, 3, 1, 5, 2}
|
||||
heapSort(&nums)
|
||||
fmt.Println("После сортировки кучей nums =", nums)
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
// File: insertion_sort.go
|
||||
// Created Time: 2022-12-12
|
||||
// Author: msk397 (machangxinq@gmail.com)
|
||||
|
||||
package chapter_sorting
|
||||
|
||||
/* Сортировка вставками */
|
||||
func insertionSort(nums []int) {
|
||||
// Внешний цикл: отсортированный диапазон [0, i-1]
|
||||
for i := 1; i < len(nums); i++ {
|
||||
base := nums[i]
|
||||
j := i - 1
|
||||
// Внутренний цикл: вставить base в правильную позицию отсортированного диапазона [0, i-1]
|
||||
for j >= 0 && nums[j] > base {
|
||||
nums[j+1] = nums[j] // Сдвинуть nums[j] на одну позицию вправо
|
||||
j--
|
||||
}
|
||||
nums[j+1] = base // Поместить base в правильную позицию
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
// File: insertion_sort_test.go
|
||||
// Created Time: 2022-12-12
|
||||
// Author: msk397 (machangxinq@gmail.com)
|
||||
|
||||
package chapter_sorting
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestInsertionSort(t *testing.T) {
|
||||
nums := []int{4, 1, 3, 1, 5, 2}
|
||||
insertionSort(nums)
|
||||
fmt.Println("После сортировки вставками nums =", nums)
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
// File: merge_sort.go
|
||||
// Created Time: 2022-12-13
|
||||
// Author: msk397 (machangxinq@gmail.com)
|
||||
|
||||
package chapter_sorting
|
||||
|
||||
/* Объединить левый и правый подмассивы */
|
||||
func merge(nums []int, left, mid, right int) {
|
||||
// Диапазон левого подмассива: [left, mid], диапазон правого подмассива: [mid+1, right]
|
||||
// Создать временный массив tmp для хранения результата слияния
|
||||
tmp := make([]int, right-left+1)
|
||||
// Инициализировать начальные индексы левого и правого подмассивов
|
||||
i, j, k := left, mid+1, 0
|
||||
// Пока в левом и правом подмассивах еще есть элементы, сравнивать их и копировать меньший во временный массив
|
||||
for i <= mid && j <= right {
|
||||
if nums[i] <= nums[j] {
|
||||
tmp[k] = nums[i]
|
||||
i++
|
||||
} else {
|
||||
tmp[k] = nums[j]
|
||||
j++
|
||||
}
|
||||
k++
|
||||
}
|
||||
// Скопировать оставшиеся элементы левого и правого подмассивов во временный массив
|
||||
for i <= mid {
|
||||
tmp[k] = nums[i]
|
||||
i++
|
||||
k++
|
||||
}
|
||||
for j <= right {
|
||||
tmp[k] = nums[j]
|
||||
j++
|
||||
k++
|
||||
}
|
||||
// Скопировать элементы временного массива tmp обратно в соответствующий диапазон исходного массива nums
|
||||
for k := 0; k < len(tmp); k++ {
|
||||
nums[left+k] = tmp[k]
|
||||
}
|
||||
}
|
||||
|
||||
/* Сортировка слиянием */
|
||||
func mergeSort(nums []int, left, right int) {
|
||||
// Условие завершения
|
||||
if left >= right {
|
||||
return
|
||||
}
|
||||
// Этап разбиения
|
||||
mid := left + (right - left) / 2
|
||||
mergeSort(nums, left, mid)
|
||||
mergeSort(nums, mid+1, right)
|
||||
// Этап слияния
|
||||
merge(nums, left, mid, right)
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
// File: merge_sort_test.go
|
||||
// Created Time: 2022-12-13
|
||||
// Author: msk397 (machangxinq@gmail.com)
|
||||
|
||||
package chapter_sorting
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestMergeSort(t *testing.T) {
|
||||
nums := []int{7, 3, 2, 6, 0, 1, 5, 4}
|
||||
mergeSort(nums, 0, len(nums)-1)
|
||||
fmt.Println("После сортировки слиянием nums =", nums)
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
// File: quick_sort.go
|
||||
// Created Time: 2022-12-12
|
||||
// Author: msk397 (machangxinq@gmail.com)
|
||||
|
||||
package chapter_sorting
|
||||
|
||||
// Быстрая сортировка
|
||||
type quickSort struct{}
|
||||
|
||||
// Быстрая сортировка (оптимизация медианным опорным элементом)
|
||||
type quickSortMedian struct{}
|
||||
|
||||
// Быстрая сортировка (оптимизация глубины рекурсии)
|
||||
type quickSortTailCall struct{}
|
||||
|
||||
/* Разбиение с опорными указателями */
|
||||
func (q *quickSort) partition(nums []int, left, right int) int {
|
||||
// Взять nums[left] в качестве опорного элемента
|
||||
i, j := left, right
|
||||
for i < j {
|
||||
for i < j && nums[j] >= nums[left] {
|
||||
j-- // Идти справа налево в поисках первого элемента меньше опорного
|
||||
}
|
||||
for i < j && nums[i] <= nums[left] {
|
||||
i++ // Идти слева направо в поисках первого элемента больше опорного
|
||||
}
|
||||
// Обмен элементов
|
||||
nums[i], nums[j] = nums[j], nums[i]
|
||||
}
|
||||
// Переместить опорный элемент на границу двух подмассивов
|
||||
nums[i], nums[left] = nums[left], nums[i]
|
||||
return i // Вернуть индекс опорного элемента
|
||||
}
|
||||
|
||||
/* Быстрая сортировка */
|
||||
func (q *quickSort) quickSort(nums []int, left, right int) {
|
||||
// Завершить рекурсию, когда длина подмассива равна 1
|
||||
if left >= right {
|
||||
return
|
||||
}
|
||||
// Разбиение с опорными указателями
|
||||
pivot := q.partition(nums, left, right)
|
||||
// Рекурсивно обработать левый и правый подмассивы
|
||||
q.quickSort(nums, left, pivot-1)
|
||||
q.quickSort(nums, pivot+1, right)
|
||||
}
|
||||
|
||||
/* Выбрать медиану из трех кандидатов */
|
||||
func (q *quickSortMedian) medianThree(nums []int, left, mid, right int) int {
|
||||
l, m, r := nums[left], nums[mid], nums[right]
|
||||
if (l <= m && m <= r) || (r <= m && m <= l) {
|
||||
return mid // m находится между l и r
|
||||
}
|
||||
if (m <= l && l <= r) || (r <= l && l <= m) {
|
||||
return left // l находится между m и r
|
||||
}
|
||||
return right
|
||||
}
|
||||
|
||||
/* Разбиение с опорными указателями (медиана трех) */
|
||||
func (q *quickSortMedian) partition(nums []int, left, right int) int {
|
||||
// Взять nums[left] в качестве опорного элемента
|
||||
med := q.medianThree(nums, left, (left+right)/2, right)
|
||||
// Переместить медиану в крайний левый элемент массива
|
||||
nums[left], nums[med] = nums[med], nums[left]
|
||||
// Взять nums[left] в качестве опорного элемента
|
||||
i, j := left, right
|
||||
for i < j {
|
||||
for i < j && nums[j] >= nums[left] {
|
||||
j-- // Идти справа налево в поисках первого элемента меньше опорного
|
||||
}
|
||||
for i < j && nums[i] <= nums[left] {
|
||||
i++ // Идти слева направо в поисках первого элемента больше опорного
|
||||
}
|
||||
// Обмен элементов
|
||||
nums[i], nums[j] = nums[j], nums[i]
|
||||
}
|
||||
// Переместить опорный элемент на границу двух подмассивов
|
||||
nums[i], nums[left] = nums[left], nums[i]
|
||||
return i // Вернуть индекс опорного элемента
|
||||
}
|
||||
|
||||
/* Быстрая сортировка */
|
||||
func (q *quickSortMedian) quickSort(nums []int, left, right int) {
|
||||
// Завершить рекурсию, когда длина подмассива равна 1
|
||||
if left >= right {
|
||||
return
|
||||
}
|
||||
// Разбиение с опорными указателями
|
||||
pivot := q.partition(nums, left, right)
|
||||
// Рекурсивно обработать левый и правый подмассивы
|
||||
q.quickSort(nums, left, pivot-1)
|
||||
q.quickSort(nums, pivot+1, right)
|
||||
}
|
||||
|
||||
/* Разбиение с опорными указателями */
|
||||
func (q *quickSortTailCall) partition(nums []int, left, right int) int {
|
||||
// Взять nums[left] в качестве опорного элемента
|
||||
i, j := left, right
|
||||
for i < j {
|
||||
for i < j && nums[j] >= nums[left] {
|
||||
j-- // Идти справа налево в поисках первого элемента меньше опорного
|
||||
}
|
||||
for i < j && nums[i] <= nums[left] {
|
||||
i++ // Идти слева направо в поисках первого элемента больше опорного
|
||||
}
|
||||
// Обмен элементов
|
||||
nums[i], nums[j] = nums[j], nums[i]
|
||||
}
|
||||
// Переместить опорный элемент на границу двух подмассивов
|
||||
nums[i], nums[left] = nums[left], nums[i]
|
||||
return i // Вернуть индекс опорного элемента
|
||||
}
|
||||
|
||||
/* Быстрая сортировка (оптимизация глубины рекурсии) */
|
||||
func (q *quickSortTailCall) quickSort(nums []int, left, right int) {
|
||||
// Завершить, когда длина подмассива равна 1
|
||||
for left < right {
|
||||
// Операция разбиения с опорными указателями
|
||||
pivot := q.partition(nums, left, right)
|
||||
// Выполнить быструю сортировку для более короткого из двух подмассивов
|
||||
if pivot-left < right-pivot {
|
||||
q.quickSort(nums, left, pivot-1) // Рекурсивно отсортировать левый подмассив
|
||||
left = pivot + 1 // Оставшийся неотсортированный диапазон: [pivot + 1, right]
|
||||
} else {
|
||||
q.quickSort(nums, pivot+1, right) // Рекурсивно отсортировать правый подмассив
|
||||
right = pivot - 1 // Оставшийся неотсортированный диапазон: [left, pivot - 1]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
// File: quick_sort_test.go
|
||||
// Created Time: 2022-12-12
|
||||
// Author: msk397 (machangxinq@gmail.com)
|
||||
|
||||
package chapter_sorting
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// Быстрая сортировка
|
||||
func TestQuickSort(t *testing.T) {
|
||||
q := quickSort{}
|
||||
nums := []int{4, 1, 3, 1, 5, 2}
|
||||
q.quickSort(nums, 0, len(nums)-1)
|
||||
fmt.Println("После быстрой сортировки nums =", nums)
|
||||
}
|
||||
|
||||
// Быстрая сортировка (оптимизация медианным опорным элементом)
|
||||
func TestQuickSortMedian(t *testing.T) {
|
||||
q := quickSortMedian{}
|
||||
nums := []int{4, 1, 3, 1, 5, 2}
|
||||
q.quickSort(nums, 0, len(nums)-1)
|
||||
fmt.Println("После быстрой сортировки (оптимизация медианным опорным элементом) nums =", nums)
|
||||
}
|
||||
|
||||
// Быстрая сортировка (оптимизация глубины рекурсии)
|
||||
func TestQuickSortTailCall(t *testing.T) {
|
||||
q := quickSortTailCall{}
|
||||
nums := []int{4, 1, 3, 1, 5, 2}
|
||||
q.quickSort(nums, 0, len(nums)-1)
|
||||
fmt.Println("После быстрой сортировки (оптимизация глубины рекурсии) nums =", nums)
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
// File: radix_sort.go
|
||||
// Created Time: 2023-01-18
|
||||
// Author: Reanon (793584285@qq.com)
|
||||
|
||||
package chapter_sorting
|
||||
|
||||
import "math"
|
||||
|
||||
/* Получить k-й разряд элемента num, где exp = 10^(k-1) */
|
||||
func digit(num, exp int) int {
|
||||
// Передача exp вместо k позволяет избежать повторного дорогостоящего вычисления степени
|
||||
return (num / exp) % 10
|
||||
}
|
||||
|
||||
/* Сортировка подсчетом (сортировка по k-му разряду nums) */
|
||||
func countingSortDigit(nums []int, exp int) {
|
||||
// Разряды десятичной системы лежат в диапазоне 0~9, поэтому нужен массив корзин длины 10
|
||||
counter := make([]int, 10)
|
||||
n := len(nums)
|
||||
// Подсчитать число появлений каждой цифры от 0 до 9
|
||||
for i := 0; i < n; i++ {
|
||||
d := digit(nums[i], exp) // Получить k-й разряд nums[i], обозначив его как d
|
||||
counter[d]++ // Подсчитать число появлений цифры d
|
||||
}
|
||||
// Вычислить префиксные суммы и преобразовать «число появлений» в «индекс массива»
|
||||
for i := 1; i < 10; i++ {
|
||||
counter[i] += counter[i-1]
|
||||
}
|
||||
// Выполняя обратный проход, заполнить res элементами по статистике в корзинах
|
||||
res := make([]int, n)
|
||||
for i := n - 1; i >= 0; i-- {
|
||||
d := digit(nums[i], exp)
|
||||
j := counter[d] - 1 // Получить индекс j цифры d в массиве
|
||||
res[j] = nums[i] // Поместить текущий элемент по индексу j
|
||||
counter[d]-- // Уменьшить количество d на 1
|
||||
}
|
||||
// Перезаписать исходный массив nums результатом
|
||||
for i := 0; i < n; i++ {
|
||||
nums[i] = res[i]
|
||||
}
|
||||
}
|
||||
|
||||
/* Поразрядная сортировка */
|
||||
func radixSort(nums []int) {
|
||||
// Получить максимальный элемент массива, чтобы определить максимальное число разрядов
|
||||
max := math.MinInt
|
||||
for _, num := range nums {
|
||||
if num > max {
|
||||
max = num
|
||||
}
|
||||
}
|
||||
// Проходить разряды от младшего к старшему
|
||||
for exp := 1; max >= exp; exp *= 10 {
|
||||
// Выполнить сортировку подсчетом по k-му разряду элементов массива
|
||||
// k = 1 -> exp = 1
|
||||
// k = 2 -> exp = 10
|
||||
// то есть exp = 10^(k-1)
|
||||
countingSortDigit(nums, exp)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
// File: radix_sort_test.go
|
||||
// Created Time: 2023-01-18
|
||||
// Author: Reanon (793584285@qq.com)
|
||||
|
||||
package chapter_sorting
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestRadixSort(t *testing.T) {
|
||||
/* Поразрядная сортировка */
|
||||
nums := []int{10546151, 35663510, 42865989, 34862445, 81883077,
|
||||
88906420, 72429244, 30524779, 82060337, 63832996}
|
||||
radixSort(nums)
|
||||
fmt.Println("После поразрядной сортировки nums =", nums)
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
// File: selection_sort.go
|
||||
// Created Time: 2023-05-29
|
||||
// Author: Reanon (793584285@qq.com)
|
||||
|
||||
package chapter_sorting
|
||||
|
||||
/* Сортировка выбором */
|
||||
func selectionSort(nums []int) {
|
||||
n := len(nums)
|
||||
// Внешний цикл: неотсортированный диапазон [i, n-1]
|
||||
for i := 0; i < n-1; i++ {
|
||||
// Внутренний цикл: найти минимальный элемент в неотсортированном диапазоне
|
||||
k := i
|
||||
for j := i + 1; j < n; j++ {
|
||||
if nums[j] < nums[k] {
|
||||
// Записать индекс минимального элемента
|
||||
k = j
|
||||
}
|
||||
}
|
||||
// Поменять этот минимальный элемент местами с первым элементом неотсортированного диапазона
|
||||
nums[i], nums[k] = nums[k], nums[i]
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
// File: selection_sort_test.go
|
||||
// Created Time: 2023-05-29
|
||||
// Author: Reanon (793584285@qq.com)
|
||||
|
||||
package chapter_sorting
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestSelectionSort(t *testing.T) {
|
||||
nums := []int{4, 1, 3, 1, 5, 2}
|
||||
selectionSort(nums)
|
||||
fmt.Println("После сортировки выбором nums =", nums)
|
||||
}
|
||||
Reference in New Issue
Block a user