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:
Yudong Jin
2026-03-28 04:24:07 +08:00
committed by GitHub
parent 2ca570cc33
commit 772183705e
1958 changed files with 108186 additions and 0 deletions
@@ -0,0 +1,79 @@
// File: array.go
// Created Time: 2022-12-29
// Author: GuoWei (gongguowei01@gmail.com), cathay (cathaycchen@gmail.com)
package chapter_array_and_linkedlist
import (
"math/rand"
)
/* Случайный доступ к элементу */
func randomAccess(nums []int) (randomNum int) {
// Случайным образом выбрать число из интервала [0, nums.length)
randomIndex := rand.Intn(len(nums))
// Получить и вернуть случайный элемент
randomNum = nums[randomIndex]
return
}
/* Увеличить длину массива */
func extend(nums []int, enlarge int) []int {
// Инициализировать массив увеличенной длины
res := make([]int, len(nums)+enlarge)
// Скопировать все элементы исходного массива в новый массив
for i, num := range nums {
res[i] = num
}
// Вернуть новый массив после расширения
return res
}
/* Вставить элемент num по индексу index в массив */
func insert(nums []int, num int, index int) {
// Сдвинуть элемент с индексом index и все последующие элементы на одну позицию назад
for i := len(nums) - 1; i > index; i-- {
nums[i] = nums[i-1]
}
// Присвоить num элементу по индексу index
nums[index] = num
}
/* Удалить элемент по индексу index */
func remove(nums []int, index int) {
// Сдвинуть все элементы после индекса index на одну позицию вперед
for i := index; i < len(nums)-1; i++ {
nums[i] = nums[i+1]
}
}
/* Обход массива */
func traverse(nums []int) {
count := 0
// Обход массива по индексам
for i := 0; i < len(nums); i++ {
count += nums[i]
}
count = 0
// Непосредственно обходить элементы массива
for _, num := range nums {
count += num
}
// Одновременно обходить индексы и элементы данных
for i, num := range nums {
count += nums[i]
count += num
}
}
/* Найти заданный элемент в массиве */
func find(nums []int, target int) (index int) {
index = -1
for i := 0; i < len(nums); i++ {
if nums[i] == target {
index = i
break
}
}
return
}
@@ -0,0 +1,50 @@
// File: array_test.go
// Created Time: 2022-12-29
// Author: GuoWei (gongguowei01@gmail.com), cathay (cathaycchen@gmail.com)
package chapter_array_and_linkedlist
/**
* Мы рассматриваем срез Slice в Go как массив Array. Это позволяет
* снизить порог понимания и сосредоточиться на структурах данных и алгоритмах.
*/
import (
"fmt"
"testing"
)
/* Driver Code */
func TestArray(t *testing.T) {
/* Инициализация массива */
var arr [5]int
fmt.Println("Массив arr =", arr)
// В Go при указании длины ([5]int) получается массив, а без указания длины ([]int) — срез
// Так как массивы в Go имеют длину, определяемую на этапе компиляции, для задания длины можно использовать только константы
// Для удобства реализации функции расширения extend() ниже срез (Slice) рассматривается как массив (Array)
nums := []int{1, 3, 2, 5, 4}
fmt.Println("Массив nums =", nums)
/* Случайный доступ */
randomNum := randomAccess(nums)
fmt.Println("Случайный элемент из nums =", randomNum)
/* Расширение длины */
nums = extend(nums, 3)
fmt.Println("После увеличения длины массива до 8 nums =", nums)
/* Вставка элемента */
insert(nums, 6, 3)
fmt.Println("После вставки числа 6 по индексу 3 nums =", nums)
/* Удаление элемента */
remove(nums, 2)
fmt.Println("После удаления элемента по индексу 2 nums =", nums)
/* Обход массива */
traverse(nums)
/* Поиск элемента */
index := find(nums, 3)
fmt.Println("Поиск элемента 3 в nums: индекс =", index)
}
@@ -0,0 +1,51 @@
// File: linked_list.go
// Created Time: 2022-12-29
// Author: cathay (cathaycchen@gmail.com)
package chapter_array_and_linkedlist
import (
. "github.com/krahets/hello-algo/pkg"
)
/* Вставить узел P после узла n0 в связном списке */
func insertNode(n0 *ListNode, P *ListNode) {
n1 := n0.Next
P.Next = n1
n0.Next = P
}
/* Удалить первый узел после узла n0 в связном списке */
func removeItem(n0 *ListNode) {
if n0.Next == nil {
return
}
// n0 -> P -> n1
P := n0.Next
n1 := P.Next
n0.Next = n1
}
/* Доступ к узлу связного списка по индексу index */
func access(head *ListNode, index int) *ListNode {
for i := 0; i < index; i++ {
if head == nil {
return nil
}
head = head.Next
}
return head
}
/* Найти в связном списке первый узел со значением target */
func findNode(head *ListNode, target int) int {
index := 0
for head != nil {
if head.Val == target {
return index
}
head = head.Next
index++
}
return -1
}
@@ -0,0 +1,48 @@
// File: linked_list_test.go
// Created Time: 2022-12-29
// Author: cathay (cathaycchen@gmail.com)
package chapter_array_and_linkedlist
import (
"fmt"
"testing"
. "github.com/krahets/hello-algo/pkg"
)
func TestLinkedList(t *testing.T) {
/* Инициализировать связный список 1 -> 3 -> 2 -> 5 -> 4 */
// Инициализация всех узлов
n0 := NewListNode(1)
n1 := NewListNode(3)
n2 := NewListNode(2)
n3 := NewListNode(5)
n4 := NewListNode(4)
// Построить ссылки между узлами
n0.Next = n1
n1.Next = n2
n2.Next = n3
n3.Next = n4
fmt.Println("Исходный связный список")
PrintLinkedList(n0)
/* Вставка узла */
insertNode(n0, NewListNode(0))
fmt.Println("Связный список после вставки узла")
PrintLinkedList(n0)
/* Удаление узла */
removeItem(n0)
fmt.Println("Связный список после удаления узла")
PrintLinkedList(n0)
/* Доступ к узлу */
node := access(n0, 3)
fmt.Println("Значение узла по индексу 3 в связном списке =", node)
/* Поиск узла */
index := findNode(n0, 2)
fmt.Println("Индекс узла со значением 2 в связном списке =", index)
}
@@ -0,0 +1,66 @@
// File: list_test.go
// Created Time: 2022-12-18
// Author: msk397 (machangxinq@gmail.com)
package chapter_array_and_linkedlist
import (
"fmt"
"sort"
"testing"
)
/* Driver Code */
func TestList(t *testing.T) {
/* Инициализация списка */
nums := []int{1, 3, 2, 5, 4}
fmt.Println("Список nums =", nums)
/* Доступ к элементу */
num := nums[1] // Обратиться к элементу по индексу 1
fmt.Println("Элемент по индексу 1: num =", num)
/* Обновление элемента */
nums[1] = 0 // Обновить элемент по индексу 1 до 0
fmt.Println("После обновления элемента по индексу 1 до 0 nums =", nums)
/* Очистить список */
nums = nil
fmt.Println("После очистки списка nums =", nums)
/* Добавление элемента в конец */
nums = append(nums, 1)
nums = append(nums, 3)
nums = append(nums, 2)
nums = append(nums, 5)
nums = append(nums, 4)
fmt.Println("После добавления элементов nums =", nums)
/* Вставка элемента в середину */
nums = append(nums[:3], append([]int{6}, nums[3:]...)...) // Вставить число 6 по индексу 3
fmt.Println("После вставки числа 6 по индексу 3 nums =", nums)
/* Удаление элемента */
nums = append(nums[:3], nums[4:]...) // Удалить элемент по индексу 3
fmt.Println("После удаления элемента по индексу 3 nums =", nums)
/* Обходить список по индексам */
count := 0
for i := 0; i < len(nums); i++ {
count += nums[i]
}
/* Непосредственно обходить элементы списка */
count = 0
for _, x := range nums {
count += x
}
/* Объединить два списка */
nums1 := []int{6, 8, 7, 10, 9}
nums = append(nums, nums1...) // Присоединить список nums1 после nums
fmt.Println("После конкатенации списка nums1 к nums nums =", nums)
/* Отсортировать список */
sort.Ints(nums) // После сортировки элементы списка располагаются по возрастанию
fmt.Println("После сортировки списка nums =", nums)
}
@@ -0,0 +1,109 @@
// File: my_list.go
// Created Time: 2022-12-18
// Author: msk397 (machangxinq@gmail.com)
package chapter_array_and_linkedlist
/* Класс списка */
type myList struct {
arrCapacity int
arr []int
arrSize int
extendRatio int
}
/* Конструктор */
func newMyList() *myList {
return &myList{
arrCapacity: 10, // Вместимость списка
arr: make([]int, 10), // Массив (для хранения элементов списка)
arrSize: 0, // Длина списка (текущее число элементов)
extendRatio: 2, // Коэффициент увеличения списка при каждом расширении
}
}
/* Получить длину списка (текущее число элементов) */
func (l *myList) size() int {
return l.arrSize
}
/* Получить вместимость списка */
func (l *myList) capacity() int {
return l.arrCapacity
}
/* Доступ к элементу */
func (l *myList) get(index int) int {
// Если индекс выходит за границы, выбрасывается исключение; далее аналогично
if index < 0 || index >= l.arrSize {
panic("индекс выходит за границы")
}
return l.arr[index]
}
/* Обновление элемента */
func (l *myList) set(num, index int) {
if index < 0 || index >= l.arrSize {
panic("индекс выходит за границы")
}
l.arr[index] = num
}
/* Добавление элемента в конец */
func (l *myList) add(num int) {
// При превышении вместимости по числу элементов запускается расширение
if l.arrSize == l.arrCapacity {
l.extendCapacity()
}
l.arr[l.arrSize] = num
// Обновить число элементов
l.arrSize++
}
/* Вставка элемента в середину */
func (l *myList) insert(num, index int) {
if index < 0 || index >= l.arrSize {
panic("индекс выходит за границы")
}
// При превышении вместимости по числу элементов запускается расширение
if l.arrSize == l.arrCapacity {
l.extendCapacity()
}
// Сдвинуть элемент с индексом index и все следующие элементы на одну позицию назад
for j := l.arrSize - 1; j >= index; j-- {
l.arr[j+1] = l.arr[j]
}
l.arr[index] = num
// Обновить число элементов
l.arrSize++
}
/* Удаление элемента */
func (l *myList) remove(index int) int {
if index < 0 || index >= l.arrSize {
panic("индекс выходит за границы")
}
num := l.arr[index]
// Сдвинуть все элементы после индекса index на одну позицию вперед
for j := index; j < l.arrSize-1; j++ {
l.arr[j] = l.arr[j+1]
}
// Обновить число элементов
l.arrSize--
// Вернуть удаленный элемент
return num
}
/* Расширение списка */
func (l *myList) extendCapacity() {
// Создать новый массив длиной в extendRatio раз больше исходного и скопировать в него исходный массив
l.arr = append(l.arr, make([]int, l.arrCapacity*(l.extendRatio-1))...)
// Обновить вместимость списка
l.arrCapacity = len(l.arr)
}
/* Вернуть список фактической длины */
func (l *myList) toArray() []int {
// Преобразовывать только элементы списка в пределах фактической длины
return l.arr[:l.arrSize]
}
@@ -0,0 +1,46 @@
// File: my_list_test.go
// Created Time: 2022-12-18
// Author: msk397 (machangxinq@gmail.com)
package chapter_array_and_linkedlist
import (
"fmt"
"testing"
)
/* Driver Code */
func TestMyList(t *testing.T) {
/* Инициализация списка */
nums := newMyList()
/* Добавление элемента в конец */
nums.add(1)
nums.add(3)
nums.add(2)
nums.add(5)
nums.add(4)
fmt.Printf("Список nums = %v, вместимость = %v, длина = %v\n", nums.toArray(), nums.capacity(), nums.size())
/* Вставка элемента в середину */
nums.insert(6, 3)
fmt.Printf("После вставки числа 6 по индексу 3 nums = %v\n", nums.toArray())
/* Удаление элемента */
nums.remove(3)
fmt.Printf("После удаления элемента по индексу 3 nums = %v\n", nums.toArray())
/* Доступ к элементу */
num := nums.get(1)
fmt.Printf("Элемент по индексу 1: num = %v\n", num)
/* Обновление элемента */
nums.set(0, 1)
fmt.Printf("После обновления элемента по индексу 1 до 0 nums = %v\n", nums.toArray())
/* Проверка механизма расширения */
for i := 0; i < 10; i++ {
// При i = 5 длина списка превысит его вместимость, и в этот момент сработает механизм расширения
nums.add(i)
}
fmt.Printf("Список nums после увеличения вместимости = %v, вместимость = %v, длина = %v\n", nums.toArray(), nums.capacity(), nums.size())
}