5.8 KiB
5.8 KiB
lab2
gleam add lab2@1
import lab2
pub fn main() -> Nil {
// TODO: An example of the project in use
}
Further documentation can be found at https://hexdocs.pm/lab2.
Development
gleam run # Run the project
gleam test # Run the tests
Red-Black Tree с ленивыми вычислениями
Описание
Реализация красно-чёрного дерева (Red-Black Tree) с ленивыми вычислениями на языке Gleam. Красно-чёрное дерево - это самобалансирующееся двоичное дерево поиска, которое гарантирует логарифмическую сложность операций вставки, удаления и поиска.
Особенности реализации
- Ленивые вычисления: Поддеревья создаются только при необходимости, что экономит память и время
- Полиморфность: Дерево работает с любыми типами ключей и значений
- Неизменяемость: Все операции создают новые версии дерева, не изменяя исходное
- Структура моноида: Поддерживает операции объединения с нейтральным элементом
API
Основные операции
empty()- создание пустого дереваinsert(tree, key, value, compare)- вставка элементаlookup(tree, key, compare)- поиск элементаdelete(tree, key, compare)- удаление элементаcontains(tree, key, compare)- проверка наличия ключа
Функции высшего порядка
map(tree, f)- отображение функции на все значенияfilter(tree, predicate, compare)- фильтрация элементовfold_left(tree, acc, f)- левая свёрткаfold_right(tree, acc, f)- правая свёртка
Операции моноида
mempty()- нейтральный элемент (пустое дерево)concat(tree1, tree2, compare)- объединение деревьев
Вспомогательные функции
size(tree)- размер дереваto_list(tree)- преобразование в списокfrom_list(list, compare)- создание из спискаkeys(tree)- получение всех ключейvalues(tree)- получение всех значенийequal(tree1, tree2, key_eq, value_eq)- сравнение деревьев
Сложность операций
| Операция | Сложность |
|---|---|
| lookup | O(log n) |
| insert | O(log n) |
| delete | O(log n) |
| size | O(n) |
| map | O(n) |
| filter | O(n) |
| fold | O(n) |
Пример использования
import lab2
import gleam/int
// Функция сравнения для целых чисел
fn int_compare(a: Int, b: Int) -> order.Order {
int.compare(a, b)
}
pub fn main() {
// Создание дерева и вставка элементов
let tree = lab2.empty()
|> lab2.insert(5, "five", int_compare)
|> lab2.insert(3, "three", int_compare)
|> lab2.insert(7, "seven", int_compare)
|> lab2.insert(1, "one", int_compare)
// Поиск элемента
case lab2.lookup(tree, 5, int_compare) {
Some(value) -> io.println("Found: " <> value)
None -> io.println("Not found")
}
// Фильтрация чётных ключей
let even_tree = lab2.filter(tree, fn(key, _) { key % 2 == 0 }, int_compare)
// Отображение: удвоение длины строк
let doubled = lab2.map(tree, fn(value) { value <> value })
// Свёртка: подсчёт элементов
let count = lab2.fold_left(tree, 0, fn(acc, _, _) { acc + 1 })
}
Свойства моноида
Структура данных удовлетворяет аксиомам моноида:
- Ассоциативность:
concat(concat(a, b), c) ≡ concat(a, concat(b, c)) - Левая единица:
concat(mempty(), a) ≡ a - Правая единица:
concat(a, mempty()) ≡ a
Тестирование
Проект включает в себя comprehensive test suite:
- Unit тесты: Проверка корректности отдельных функций
- Property-based тесты: Проверка инвариантов и свойств структуры данных
- Тесты моноида: Проверка аксиом моноида
Запуск тестов:
gleam test
Инварианты красно-чёрного дерева
- Каждый узел либо красный, либо чёрный
- Корень дерева чёрный
- Все листья (NULL-узлы) чёрные
- Если узел красный, то оба его потомка чёрные
- Для каждого узла все пути от него до листьев содержат одинаковое количество чёрных узлов
Эти инварианты гарантируют, что самый длинный путь от корня до листа не более чем в 2 раза длиннее самого короткого пути, что обеспечивает логарифмическую сложность операций.