Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Структуры данных

Нет структуры данных, которая была бы лучшей для всех операций. Приходится чем-то жертвовать. Каждая структура представляет собой компромисс между скоростью поиска, вставки и удаления, расходом памяти, упорядоченностью данных и другими характеристиками. Выбор зависит от конкретной задачи.

В языках программирования/библиотеках уже есть реализации структур данных, так что в первую очередь, имеет смысл освоить их применение т.е. хорошо понимать сильные и слабые стороны и применимость к задаче. Реализовывать очередной linked list не имеет смылса, так как это не дает понимание его применения. Когда будет понимание поведения основных структур данных, тогда можно реализовывать собственные структуры, комбинируя нужные свойства стандарных структур данных.

Для практики важнее научиться узнавать профиль нагрузки и выбирать структуру под него.

Содержание


Array

Визуализация работы Array

Массив — как абстрактная модель, это последовательность однородных элементов с индексированным произвольным доступом.

Конкретные реализации модели массива: Static Array, Dynamic Array, Multidimensional Array

Array ознакомление

Сильные стороны

  • Мгновенный доступ: Доступ к абсолютно любому элементу по целочисленному индексу за константное время
  • Очень быстрый последовательный обход из-за меньшего обращения к RAM и простого расчета индекса следующего элемента address = base_address + index * type_size
  • Кэш-локальность (Spatial Locality): Элементы расположены подряд, что обеспечивает максимальную эффективность L1/L2/L3 кэшей процессора
  • Низкий Memory Overhead: Нет затрат на хранение дополнительных указателей

Слабые стороны

  • Дорогие вставки и удаления: Любое изменение структуры внутри массива требует сдвига всей последующей последовательности
  • Фрагментация памяти: Требуется непрерывный фрагмент памяти. При выделении огромных массивов системный аллокатор может вернуть ошибку, даже если суммарный объем свободной памяти достаточен
  • Избыточное выделение: При геометрическом изменении размера (например, ) часть памяти остается незадействованной
  • Поиск за
  • Обычный статический массив требует заранее известного размера
  • Плохо подходит, если основной способ доступа — не индекс, а произвольный ключ

Сложность операций

ОперацияСреднееХудшееПочему
ДоступO(1)O(1)адрес вычисляется по индексу
ПоискO(n)O(n)последовательный просмотр
Добавление в начало/серединуO(n)O(n)требуется сдвиг
Добавление в конец--O(1) для динамического массива
УдалениеO(n)O(n)требуется сдвиг

Память

  • Нет затрат на хранение дополнительных указателей
  • Элементы расположены последовательно.
  • Почти нет дополнительной памяти на связи между элементами.
  • Dynamic array обычно резервирует свободную ёмкость.

Когда использовать

  • Порядок элементов важен
  • Размер коллекции известен заранее или меняется редко.
  • Преобладают операции чтения и случайного доступа.
  • Требуется максимальная производительность по скорости прохода (iteration speed).
  • Частый доступ по позиции.

Когда не использовать

  • Необходимы частые вставки и удаления в произвольные места коллекции
  • Точный размер данных заранее неизвестен, а выделять память с запасом недопустимо из-за жестких ограничений по RAM
  • Нужны быстрые range-запросы при постоянных изменениях данных

Алгоритмы, связанные с массивом

Linear Search
Binary Search
Two Pointers
Sliding Window
Prefix Sum
Sorting

Задачи

Насколько массив подходит, где возникнут проблемы, какие его свойства используются:

  • index access — доступ по индексу. Если нужен 1000-й элемент, массив позволяет обратиться к нему напрямую: array[999]. Обычно это
  • contiguous memory — непрерывное размещение в памяти. Элементы массива лежат рядом друг с другом: [A][B][C][D]. Это позволяет быстро вычислять адрес элемента по индексу
  • cache locality — хорошая локальность данных. Поскольку элементы лежат рядом, процессор часто загружает сразу несколько соседних элементов в кэш. Поэтому последовательный обход массива обычно очень быстрый
  • fixed size — фиксированный размер. Обычный массив создаётся на определённое число элементов, и сам по себе увеличиться не может
  • dynamic resizing — динамическое расширение. Dynamic array (Vec, vector, ArrayList) при нехватке места создаёт новый более крупный массив и переносит туда элементы
  • amortized complexity — амортизированная сложность. Отдельная операция иногда может быть дорогой, но если смотреть на длинную серию операций, средняя стоимость остаётся маленькой. Например push в dynamic array обычно считается amortized, хотя иногда когда dynamic array заполнен и ему нужно расшириться resize стоит
  • shifting — сдвиг элементов. Если вставить или удалить элемент в середине массива и нужно сохранить порядок, остальные элементы приходится перемещать
  • ordered deletion — удаление с сохранением порядка
  • unordered deletion — удаление без сохранения порядка. Если порядок не важен, удаляемый элемент можно заменить последним
  • linear search — линейный поиск. Идём по элементам один за другим, пока не найдём нужный
  • sorted array + binary search — отсортированный массив + бинарный поиск
  • sparse indexes — разреженные индексы. Возможные значения очень далеко друг от друга
  • dense indexes — плотные индексы. Значения индексов идут почти подряд
  • memory overhead — дополнительная память, которую структура тратит помимо самих данных. У массива overhead обычно небольшой. Например для int в основном хранятся сами числа

info

Какие операции над данными нужны и насколько часто они выполняются?


example

№1 ключ и индекс

Есть массив из 10 миллионов пользователей.

У каждого пользователя есть: id, name, email

Программа выполняет два типа запросов:

  • получить пользователя № 5000000
  • получить пользователя с id = 87342873

Порядковый номер пользователя и id никак не связаны.

Подходит ли массив?
  • Для получения пользователя по номеру, массив подходит
  • Для получения пользователя по полю id придется выполнять поиск по значению, это плохо подходит массиву. Для поиска по id логичнее добавить hash table или другой индекс.

example

№2 последовательность

Есть список из миллиона песен.

Пользователь постоянно удаляет песни из разных мест плейлиста.

Оставшиеся песни должны сохранить исходный порядок.

Подходит ли массив?
  • Если бы порядок был неважен, то мы могли бы заменять дыры последовательности последним элементом, но в данном случае массив неподходит из-за дорогой операции смещения всех элементов после удаления

example

№3 последовательность

Есть массив игровых объектов.

Порядок объектов не важен.

Нужно очень часто удалять произвольный объект.

Подходит ли массив?
  • Можно избежать сдвига элементов после удаления если переместить последний элемент на освободившееся место, тогда удаление может быть за и мы можем использовать массив.

example

№4 cache locality

Есть два варианта хранения 100 миллионов чисел:

  • одно непрерывное хранилище
  • списком (элементы разбросаны по памяти и связаны указателями)

Основная операция - суммирование всех элементов

Подходит ли массив?
  • Для суммирования элементов необходимо проходить весь массив, тут хорошо подходит массив. Список будет иметь накладные расходы на прыжок по ссылке.

CPU загружает память блоками cache line. Поэтому последовательный обход массива обычно очень эффективен.


example

№5 бинарный поиск

Есть миллион отсортированных чисел. Новые элементы почти никогда не добавляются.

Нужно очень часто проверять: есть ли число X?

Подходит ли массив?
  • Да. Поскольку массив отсортирован, можно использовать binary search за

example

№6 цена поддержания сортировки

Есть миллион отсортированных чисел.

Каждую секунду:

  • 1000 раз вставить новое число
  • 100 раз выполнить поиск

Массив должен постоянно оставаться отсортированным.

Подходит ли массив?
  • Нет. Поиск мы можем выполнить быстро за используя binary search, но частое добавление в массив потребует новой сортировки

example

№7 неизвестный размер

Программа получает данные из сети. Количество элементов неизвестно.

Нужно сохранять каждый полученный элемент.

Подходит ли массив?
  • Статический массив (static) не подходит, а динамичсекий (dynamic) подходит

example

№8 разреженый индекс

В системе хранятся 50 миллионов объектов. Для каждого объекта известен уникальный идентификатор.

Основная операция программы:

получить объект по его идентификатору.

Идентификаторы выглядят примерно так:

1847293847
51
98237 
7349283
...
Можно ли использовать id непосредственно как индекс массива?
  • Технически иногда можно, но здесь получится огромный разреженный массив с множеством пустых ячеек. Это плохое использование памяти. Hash table значительно естественнее подходит

example

№9 range query

Есть 20 миллионов отсортированных цен.

Очень часто выполняется: найти все цены от 50 до 100

Изменения происходят редко.

Подходит ли массив?
  • Да, в отсортированном массиве можно использовать бинарный поиск и редкие изменения (удаления) так же на пользу массиву.

example

№10

Нужно хранить 500 миллионов int32

Рассматриваются две структуры:

  • array
  • linked list

В обеих полный обход занимает VSRfr

Значит ли это, что они примерно одинаковы?

Нет.

  • Память. Массив хранит примерно , а Linked list кроме самого значения обычно хранит как минимум указатель, а также возможен padding и узлы списка могут быть разбросаны по памяти.

  • Доступ. У массива адрес элемента вычисляется напрямую: . Поэтому array[500] → сразу переход к 500-му элементу: . У односвязного списка нет возможности вычислить адрес 500-го элемента по его индексу, ему нужно последовательно дойти до него за . У списка нет cache locality, каждый переход требует загрузки следующего адреса



Упражнения

Пример с двумерным массивом на C

example from ideone.com

#include <stdio.h>
#include <stdlib.h> // EXIT_SUCCESS

#define COLS 9

void variant_a(int (*arr)[COLS], size_t n ){
    printf("variant_a:\n");
    for (size_t i=0; i < n; i++){
        printf("Ряд %ld:    ",i);  
        for (size_t j=0; j < COLS; j++){
            if(j>=i) printf("0 "); 
            else printf("%d ", arr[i][j]);
        }
        printf("\n");
    }
    printf("\n");
}

void fill_out(int (*arr)[COLS], size_t n, int fill){
    for (size_t i=0; i < n; i++){
        for (size_t j=0; j < COLS; j++){
            arr[i][j]=fill;//rand()%10-5;// от -5 до +5
        }
    }
}

int main(void) { 
    const size_t n=9;
    int arr[n][COLS]; 
    fill_out(arr, n, 1);
    variant_a(arr, n);
   
    return EXIT_SUCCESS;
}

Примеры с двумерным массивом на Rust

A:


const COLS: usize = 9;

fn variant_a(arr: &[[i32; COLS]], n: usize) {
    println!("variant_a:");

    for i in 0..n {
        print!("Ряд {:<4}", i);

        for j in 0..COLS {
            if j >= i {
                print!("0 ");
            } else {
                print!("{} ", arr[i][j]);
            }
        }
        println!();
    }
    println!();
}
fn fill_out(arr: &mut [[i32; COLS]], n: usize, fill: i32) {
    for i in 0..n {
        for j in 0..COLS {
            arr[i][j] = fill;
        }
    }
}
fn main() {
    let n = 9;
    let mut arr = [[0i32; COLS]; 9];
    fill_out(&mut arr, n, 1);
    variant_a(&arr, n);
}

B:


const COLS: usize = 9;

fn variant_b(arr: &[[i32; COLS]], n: usize) {
    println!("variant_b:");

    for i in 0..n {
        print!("Ряд {:<4}", i);

        for j in 0..COLS {
            if j <= i {
                print!("0 ");
            } else {
                print!("{} ", arr[i][j]);
            }
        }
        println!();
    }
    println!();
}
fn fill_out(arr: &mut [[i32; COLS]], n: usize, fill: i32) {
    for i in 0..n {
        for j in 0..COLS {
            arr[i][j] = fill;
        }
    }
}
fn main() {
    let n = 9;
    let mut arr = [[0i32; COLS]; 9];
    fill_out(&mut arr, n, 1);
    variant_b(&arr, n);
}

C:


const COLS: usize = 9;

fn variant_c(arr: &[[i32; COLS]], n: usize) {
    println!("variant_c:");

    for i in 0..n {
        print!("Ряд {:<4}", i);

        for j in 0..COLS {
            if j >= i && j < n - i && i <= n / 2 {
                print!("0 ");
            } else {
                print!("{} ", arr[i][j]);
            }

            // Альтернативный вариант:
            // if j >= i && j < n - i {
            //     print!("0 ");
            // } else {
            //     print!("{} ", arr[i][j]);
            // }
        }
        println!();
    }
    println!();
}
fn fill_out(arr: &mut [[i32; COLS]], n: usize, fill: i32) {
    for i in 0..n {
        for j in 0..COLS {
            arr[i][j] = fill;
        }
    }
}
fn main() {
    let n = 9;
    let mut arr = [[0i32; COLS]; 9];
    fill_out(&mut arr, n, 1);
    variant_c(&arr, n);
}

D:


const COLS: usize = 9;

fn variant_d(arr: &[[i32; COLS]], n: usize) {
    println!("variant_d:");

    for i in 0..n {
        print!("Ряд {:<4}", i);

        for j in 0..COLS {
            if j <= i && j >= n - i - 1 && i >= n / 2 {
                print!("0 ");
            } else {
                print!("{} ", arr[i][j]);
            }
        }
        println!();
    }
    println!();
}
fn fill_out(arr: &mut [[i32; COLS]], n: usize, fill: i32) {
    for i in 0..n {
        for j in 0..COLS {
            arr[i][j] = fill;
        }
    }
}
fn main() {
    let n = 9;
    let mut arr = [[0i32; COLS]; 9];
    fill_out(&mut arr, n, 1);
    variant_d(&arr, n);
}

E:


const COLS: usize = 9;

fn variant_e(arr: &[[i32; COLS]], n: usize) {
    println!("variant_e:");

    for i in 0..n {
        print!("Ряд {:<4}", i);

        for j in 0..COLS {
            if (j >= i && j < n - i && i <= n / 2)
                || (j <= i && j >= n - i - 1 && i >= n / 2)
            {
                print!("0 ");
            } else {
                print!("{} ", arr[i][j]);
            }

            // Альтернативный вариант:
            // if (j >= i && j < n - i)
            //     || (j <= i && j >= n - i - 1)
            // {
            //     print!("0 ");
            // } else {
            //     print!("{} ", arr[i][j]);
            // }
        }
        println!();
    }
    println!();
}
fn fill_out(arr: &mut [[i32; COLS]], n: usize, fill: i32) {
    for i in 0..n {
        for j in 0..COLS {
            arr[i][j] = fill;
        }
    }
}
fn main() {
    let n = 9;
    let mut arr = [[0i32; COLS]; 9];
    fill_out(&mut arr, n, 1);
    variant_e(&arr, n);
}

F:


const COLS: usize = 9;

fn variant_f(arr: &[[i32; COLS]], n: usize) {
    println!("variant_f:");

    for i in 0..n {
        print!("Ряд {:<4}", i);

        for j in 0..COLS {
            if ((j < n - i && i >= n / 2)
                || (j <= i && i <= n / 2))
                || ((j >= i && i >= n / 2)
                    || (j >= n - i - 1 && i <= n / 2))
            {
                print!("0 ");
            } else {
                print!("{} ", arr[i][j]);
            }

            // Альтернативный вариант:
            // if (j <= i && j < n - i)
            //     || (j >= i && j >= n - i - 1)
            // {
            //     print!("0 ");
            // } else {
            //     print!("{} ", arr[i][j]);
            // }
        }
        println!();
    }
    println!();
}
fn fill_out(arr: &mut [[i32; COLS]], n: usize, fill: i32) {
    for i in 0..n {
        for j in 0..COLS {
            arr[i][j] = fill;
        }
    }
}
fn main() {
    let n = 9;
    let mut arr = [[0i32; COLS]; 9];
    fill_out(&mut arr, n, 1);
    variant_f(&arr, n);
}

G:


const COLS: usize = 9;

fn variant_g(arr: &[[i32; COLS]], n: usize) {
    println!("variant_g:");

    for i in 0..n {
        print!("Ряд {:<4}", i);

        for j in 0..COLS {
            if (j < n - i && i >= n / 2)
                || (j <= i && i <= n / 2)
            {
                print!("0 ");
            } else {
                print!("{} ", arr[i][j]);
            }
        }
        println!();
    }
    println!();
}
fn fill_out(arr: &mut [[i32; COLS]], n: usize, fill: i32) {
    for i in 0..n {
        for j in 0..COLS {
            arr[i][j] = fill;
        }
    }
}
fn main() {
    let n = 9;
    let mut arr = [[0i32; COLS]; 9];
    fill_out(&mut arr, n, 1);
    variant_g(&arr, n);
}

H:


const COLS: usize = 9;

fn variant_h(arr: &[[i32; COLS]], n: usize) {
    println!("variant_h:");

    for i in 0..n {
        print!("Ряд {:<4}", i);

        for j in 0..COLS {
            if (j >= i && i >= n / 2)
                || (j >= n - i - 1 && i <= n / 2)
            {
                print!("0 ");
            } else {
                print!("{} ", arr[i][j]);
            }
        }
        println!();
    }
    println!();
}
fn fill_out(arr: &mut [[i32; COLS]], n: usize, fill: i32) {
    for i in 0..n {
        for j in 0..COLS {
            arr[i][j] = fill;
        }
    }
}
fn main() {
    let n = 9;
    let mut arr = [[0i32; COLS]; 9];
    fill_out(&mut arr, n, 1);
    variant_h(&arr, n);
}

I:


const COLS: usize = 9;

fn variant_i(arr: &[[i32; COLS]], n: usize) {
    println!("variant_i:");

    for i in 0..n {
        print!("Ряд {:<4}", i);

        for j in 0..COLS {
            if j < n - i {
                print!("0 ");
            } else {
                print!("{} ", arr[i][j]);
            }
        }
        println!();
    }
    println!();
}
fn fill_out(arr: &mut [[i32; COLS]], n: usize, fill: i32) {
    for i in 0..n {
        for j in 0..COLS {
            arr[i][j] = fill;
        }
    }
}
fn main() {
    let n = 9;
    let mut arr = [[0i32; COLS]; 9];
    fill_out(&mut arr, n, 1);
    variant_i(&arr, n);
}

J:


const COLS: usize = 9;

fn variant_j(arr: &[[i32; COLS]], n: usize) {
    println!("variant_j:");

    for i in 0..n {
        print!("Ряд {:<4}", i);

        for j in 0..COLS {
            if j >= n - i {
                print!("0 ");
            } else {
                print!("{} ", arr[i][j]);
            }
        }
        println!();
    }
    println!();
}
fn fill_out(arr: &mut [[i32; COLS]], n: usize, fill: i32) {
    for i in 0..n {
        for j in 0..COLS {
            arr[i][j] = fill;
        }
    }
}
fn main() {
    let n = 9;
    let mut arr = [[0i32; COLS]; 9];
    fill_out(&mut arr, n, 1);
    variant_j(&arr, n);
}


Linked List

Визуализация работы Linked List

Linked List — связный список, это последовательность элементов, где каждый элемент хранится в отдельном узле и содержит ссылку на следующий элемент.

Конкретные реализации: Singly Linked List, Doubly Linked List, Circular Linked List

Linked List ознакомление

Сильные стороны

  • Быстрая вставка и удаление уже найденного узла без сдвига остальных элементов
  • Размер структуры может динамически изменяться
  • Не требуется непрерывный участок памяти
  • Можно эффективно добавлять элементы в начало списка
  • В Doubly Linked List можно эффективно удалять узел и двигаться в обе стороны

Слабые стороны

  • Нет произвольного доступа по индексу: чтобы получить элемент №1000, нужно пройти предыдущие 999 элементов
  • Плохая cache locality: узлы могут находиться в разных местах памяти
  • Дополнительные затраты памяти на указатели next, а в Doubly Linked List ещё и prev
  • Последовательный обход обычно медленнее массива
  • Binary Search практически теряет смысл, потому что невозможно быстро получить элемент в середине
  • Чтобы удалить элемент, его сначала обычно нужно найти

Сложность операций

ОперацияСреднееХудшееПочему
Доступ по индексуO(n)O(n)необходимо пройти список
Поиск значенияO(n)O(n)последовательный просмотр
Добавление в началоO(1)O(1)меняется только head
Добавление после известного узлаO(1)O(1)меняется несколько ссылок
Добавление в конецO(1)*O(1)*если хранится tail
Удаление после известного узлаO(1)O(1)меняется ссылка
Удаление известного узла в Doubly Linked ListO(1)O(1)доступны prev и next
Поиск + удалениеO(n)O(n)сначала нужно найти узел
  • Если tail не хранится, добавление в конец Singly Linked List требует обхода и будет O(n).

Память

Каждый элемент хранится не только вместе со значением, но и с дополнительными ссылками

Singly Linked List: [data | next]

Doubly Linked List: [prev | data | next]

Узлы могут быть расположены в памяти независимо друг от друга.

Когда использовать

  • Часто вставляются и удаляются элементы внутри последовательности
  • Уже имеется ссылка на место вставки или удаления
  • Не требуется частый доступ по индексу
  • Размер коллекции постоянно меняется
  • Нельзя или нежелательно требовать непрерывный участок памяти
  • Нужно часто добавлять элементы в начало
  • Нужно реализовать структуру, основанную на последовательном переходе между элементами

Когда не использовать

  • Нужен частый доступ к элементам по индексу
  • Основная операция — последовательный полный обход большой коллекции
  • Важна cache locality
  • Важен минимальный Memory Overhead
  • Требуется Binary Search
  • Вставки и удаления редкие, а чтение и обход происходят постоянно

Алгоритмы и структуры, связанные с Linked List

Linked List Traversal
Insertion / Deletion
Reverse Linked List
Fast & Slow Pointers
Cycle Detection
Merge Two Sorted Lists
Stack
Queue
LRU Cache

Задачи

Насколько Linked List подходит, где возникнут проблемы, какие его свойства используются:

  • pointer traversal — следующий элемент определяется ссылкой next, а не вычислением адреса
  • sequential access — доступ к элементам только последовательный
  • no contiguous memory — узлы не обязаны лежать рядом в памяти
  • node insertion — вставка рядом с известным узлом требует только изменения ссылок
  • node deletion — удаление известного узла не требует сдвига остальных элементов
  • head / tail — ссылки на первый и последний элементы списка
  • memory overhead — каждый узел дополнительно хранит указатели
  • poor cache locality — соседние логические элементы могут находиться далеко друг от друга в памяти
  • singly vs doubly linked — в односвязном списке есть только next, в двусвязном next и prev
  • search before modification — операция изменения может быть O(1), но поиск нужного места остаётся O(n)
  • pointer stability — добавление других узлов обычно не перемещает уже существующие узлы
  • fast/slow pointers — два указателя могут двигаться по списку с разной скоростью

info

Какие операции над данными нужны и насколько часто они выполняются?

important

Linked List не «быстро вставляет и удаляет».

Linked List быстро вставляет и удаляет, если нужное место уже найдено.


example

№1 доступ по индексу

Есть список из 10 миллионов объектов.

Программа очень часто выполняет:

получить объект №5
получить объект №500000
получить объект №9000000
Подходит ли Linked List?
  • Нет. Linked List не имеет прямого доступа по индексу.
  • Чтобы получить элемент №500000, нужно последовательно пройти предыдущие элементы.
  • Доступ по позиции занимает O(n).
  • Здесь массив подходит значительно лучше.

example

№2 вставка после известного элемента

Есть последовательность элементов.

Программа уже имеет ссылку на узел:

A → B → C → D
        ↑
      current

Нужно вставить X после C.

Подходит ли Linked List?
  • Да.
  • Не нужно перемещать D или другие элементы.
  • Достаточно изменить ссылки:
C.next = X
X.next = D
  • Вставка после уже известного узла выполняется за O(1).

example

№3 поиск + удаление

Есть Linked List из миллиона пользователей.

Нужно удалить пользователя с:

id = 87342873

Ссылки на узел заранее нет.

Удаление будет O(1)?

Нет. Само изменение ссылок может занимать O(1), но сначала нужно найти нужный узел: head → ... → ... → target

Поиск занимает O(n).

Поэтому вся операция: find + delete = O(n)

Это важное ограничение утверждения:

«Linked List быстро удаляет элементы».

Он быстро удаляет уже найденный элемент.


example

№4 частые вставки в начало

Программа постоянно получает новые события.

Новое событие всегда нужно добавлять в начало коллекции:

new → old_head → ...

Операция происходит миллионы раз.

Подходит ли Linked List?
  • Да.
  • Новый узел указывает на старый head.
  • После этого head заменяется новым узлом.
  • Не нужно перемещать остальные элементы.
new.next = head
head = new

Сложность O(1).


example

№5 последовательный обход

Нужно хранить 100 миллионов чисел.

Главная операция:

for each element:
    sum += element

Рассматриваются: Array и Linked List, обе структуры выполняют поиск за .

Одинаково ли хорошо подходит Linked List?

Нет. У массива элементы лежат последовательно:

[A][B][C][D]

У Linked List:

A → B → C → D

логическая последовательность не означает физическую последовательность в памяти.

Каждый переход требует:

  1. прочитать next;
  2. перейти по новому адресу;
  3. возможно загрузить новую область памяти в CPU cache.

Поэтому Linked List имеет худшую cache locality и обычно значительно хуже подходит для массового последовательного обхода.


example

№6 размер постоянно меняется

Количество объектов заранее неизвестно.

В течение работы программа постоянно: добавляет и удаляет элементы

Позиционный доступ практически не используется.

Подходит ли Linked List?

Может подходить.

Linked List не требует заранее задавать capacity и не выполняет resize всей коллекции.

Каждый новый элемент создаётся как отдельный узел.

Но этого требования самого по себе недостаточно, чтобы выбрать Linked List: dynamic array тоже умеет эффективно изменять размер.

Нужно смотреть на характер вставок и удалений:

  • если они происходят в известных местах списка — Linked List может быть удобен;
  • если элементы в основном добавляются в конец — Vec часто будет быстрее;
  • если нужен частый полный обход — массив обычно выгоднее.

example

№7 удаление известного узла

Есть Doubly Linked List:

A ⇄ B ⇄ C ⇄ D

Программа уже имеет ссылку на C.

Нужно удалить C.

Насколько это дорого?

Удаление можно сделать за O(1).

У C есть:

C.prev = B
C.next = D

Можно изменить ссылки:

B.next = D
D.prev = B

Получаем:

A ⇄ B ⇄ D

Не требуется ни сдвиг элементов, ни обход списка.


example

№8 Singly против Doubly Linked List

Есть Singly Linked List:

A → B → C → D

Программа имеет только ссылку на C.

Нужно удалить именно C.

Можно ли сделать это так же просто, как в Doubly Linked List?

Не совсем.

Чтобы удалить C обычным способом, нужно изменить:

B.next = D

Но из C нельзя напрямую получить B, потому что Singly Linked List хранит только:

C.next

Поэтому обычно нужно либо:

  • заранее иметь ссылку на предыдущий узел;
  • либо найти B, начиная с head.

Это одна из причин, почему Doubly Linked List хранит prev.


example

№9 память

Нужно хранить 100 миллионов int64

Рассматриваются:

Array
Singly Linked List
Doubly Linked List
Какая структура имеет больший Memory Overhead?

В массиве каждый элемент в основном содержит только данные, т.е. нет Memory Overhead:

[value][value][value]

Singly Linked List уже содержит дополнительно ссылку next:

[value | next]

Doubly Linked List имеет самый большой Memory Overhead, к каждому значению добавляются две ссылки:

[prev | value | next]

То есть к каждому значению добавляются указатели.

Для маленьких значений вроде int64 размер указателей может составлять значительную долю общей памяти.

Кроме того, отдельное выделение каждого узла может иметь дополнительные расходы allocator.


example

№10 Binary Search

Есть отсортированный Linked List из миллиона чисел.

Нужно часто проверять:

есть ли число X?

Можно ли использовать Binary Search за ?

Подходит ли Binary Search?

Практически нет.

Binary Search требует быстро получать средний элемент: middle

В Array array[mid] это , а в Linked List, чтобы получить mid, нужно пройти до него по ссылкам это за

Поэтому главное преимущество Binary Search теряется.

Для частого поиска отсортированный массив или дерево обычно подходят лучше.


example

№11 очередь

Нужно реализовать очередь:

добавить элемент в конец - push_back
забрать элемент из начала - pop_front
Подходит ли Linked List?

Да, если хранить:

head
tail

Добавление за :

tail.next = new
tail = new

Удаление первого за :

head = head.next

Linked List естественно подходит для реализации Queue.

Хотя на практике ring buffer / deque на основе массива часто может быть быстрее из-за cache locality.


example

№12 стабильность адресов

Есть коллекция объектов.

Другие части программы хранят ссылки на отдельные элементы коллекции.

Новые элементы постоянно добавляются.

Важно, чтобы добавление новых элементов не перемещало уже существующие объекты.

Как здесь ведёт себя Linked List?

Это сильная сторона Linked List.

Каждый узел выделен отдельно:

A at 1000
B at 8000
C at 15000

Добавление D не требует переносить A, B, C.

Их адреса остаются прежними.

У dynamic array при resize элементы могут быть перенесены в новый участок памяти.

Поэтому в некоторых задачах стабильность адресов элементов важнее скорости обхода.


example

№13 поиск по ID

Есть 10 миллионов объектов.

Основная операция: найти объект по id

ID произвольные:

92713
4
81726342
...
Подходит ли Linked List?

Нет.

Linked List не имеет быстрого поиска по ключу.

Чтобы найти нужный id, придётся последовательно проходить узлы за

Hash Table подходит значительно лучше.

Linked List может использоваться вместе с Hash Table, если нужны другие свойства списка.


example

№14 LRU Cache

Нужно реализовать cache фиксированного размера.

Когда элемент используется, он должен становиться самым «свежим».

Когда cache заполнен, нужно быстро удалить самый давно неиспользуемый элемент.

Требования:

найти элемент по key      быстро
переместить элемент       быстро
удалить старейший         быстро
Подходит ли Linked List?

Один Linked List — нет, потому что поиск по key будет .

Но хорошо работает комбинация:

HashMap + Doubly Linked List

HashMap даёт поиск в среднем:

key → node

Doubly Linked List позволяет за O(1):

удалить node из текущего места
переместить его в начало
удалить последний элемент

Это классический пример того, что структуры данных часто используются совместно.


example

№15 cycle

Из-за ошибки список получился таким:

A → B → C → D
        ↑     |
        └─────┘

То есть D.next снова указывает на C

Обычный обход никогда не завершится:

while node != null

Можно ли обнаружить цикл без хранения всех посещённых узлов?

Как?

Да. Алгоритм Floyd's Cycle Detection, используется для определения, есть ли цикл в связном списке.

Используются два указателя:

slow → двигается на 1 узел
fast → двигается на 2 узла т.е. не останавливается на первом

Если цикла нет, fast достигнет null.

Если цикл есть, в какой-то момент slow окажется в зацикленности вместе с fast и догонит его, иначе бы slow не смог бы догнать fast.

Это классическое применение техники: fast & slow pointers


example

№16 вставка в середину, но позиция задана индексом

Есть Linked List из миллиона элементов.

Нужно вставить новый элемент: на позицию №750000

Будет ли вставка O(1)?

Нет. После того как нужный узел найден, изменение ссылок действительно O(1).

Но сначала необходимо дойти до позиции №750000 за

Поэтому:

найти позицию + вставить = O(n)

Linked List особенно выгоден тогда, когда место изменения уже известно через ссылку на узел, а не задано индексом.


example

№17 вставка миллиона элементов между двумя известными позициями

Есть известный узел A и нужно последовательно добавить после него миллион новых элементов.

Сравниваются: Array и Linked List

Где Linked List получает преимущество?

Если каждый новый элемент вставляется внутрь существующей последовательности массива, массиву приходится постоянно сдвигать элементы.

У Linked List можно создавать узлы и менять ссылки без перемещения остальных элементов.

Однако если задача допускает заранее собрать все новые элементы и использовать один большой непрерывный массив, преимущество может исчезнуть. Мы можем использовать эффективное блочное копирование памяти вроде memcpy что бы скопировать левую часть исходного массива и вставить ее в подготовленный пустой массив с заранее выделенным обьемом памяти и после вставить новый миллион элементов избегая многократного перераспределения памяти и повторных сдвигов, и завершить оставшейся частью исходного массива. Но старые элементы всё равно нужно скопировать в новый массив, поэтому общая стоимость остаётся порядка , где n — размер исходного массива, а k — количество новых элементов.

То есть важна не только операция «вставка», но и способ организации всей задачи.


example

№18 список маленьких объектов

Нужно хранить миллионы значений размером всего 1–4 байта.

Выбирают Linked List, потому что «он гибкий и легко растёт».

Есть ли проблема?

Да Linked List даст лишний Memory Overhead.

Если значение занимает, например, 4 байта, а указатель — 8 байт, узел Singly Linked List уже логически содержит:

4 bytes data
8 bytes next

плюс возможный padding и расходы allocator.

То есть служебных данных может оказаться больше, чем полезных.

Для огромного количества маленьких объектов массив часто намного эффективнее по памяти.



Упражнения

Пример на С. Реализация Singly Linked List

example from ideone.com

#include <stdio.h>
#include <stdlib.h>

typedef struct Node {
    int value;
    struct Node *next;
} Node;


// Поиск узла по значению
// Возвращает найденный узел, а через prev записываеем предыдущий
Node *find_node(Node *head, int value, Node **prev){
    Node *current = head;
    *prev = NULL;
    while (current != NULL) {
        if (current->value == value) {
            return current;
        }
        *prev = current;
        current = current->next;
    }
    return NULL;
}

// Удаление узла из односвязного списка
void remove_node(Node **head, Node *node, Node *prev){
    if (node == NULL) {
        return;
    }
    if (prev == NULL) {
        // удаляем первый узел
        *head = node->next;
    } else {
        // перепрыгиваем через удаляемый узел
        prev->next = node->next;
    }
    free(node);
}

int main(void){
    Node *head = malloc(sizeof(Node));
    Node *second = malloc(sizeof(Node));
    Node *third = malloc(sizeof(Node));

    head->value = 10;
    head->next = second;

    second->value = 20;
    second->next = third;

    third->value = 30;
    third->next = NULL;

    // Создаём новый узел
    Node *new_node = malloc(sizeof(Node));
    new_node->value = 25;
    //   вставляем его между second и third
    new_node->next = second->next;
    second->next = new_node;

    // Удаление из середины
    //   находим узел 20
    Node *prev = NULL; // prev необходим что бы связать предыдущий узел со следующим
    Node *node = find_node(head, 20, &prev);
    //   удаляем найденный узел
    if (node != NULL) {
        remove_node(&head, node, prev);
    }

    // Проходим по списку
    Node *current = head;
    while (current != NULL) {
        printf("%d\n", current->value);// 10 25 30
        current = current->next;
    }

    // Освобождаем оставшиеся узлы
    current = head;
    while (current != NULL) {
        Node *next = current->next;
        free(current);
        current = next;
    }

    return 0;
}

Пример на С. Реализация Doubly Linked List

example from ideone.com

#include <stdio.h>
#include <stdlib.h>

typedef struct Node {
    int value;

    struct Node *prev;
    struct Node *next;
} Node;

typedef struct {
    Node *head;
    Node *tail;
} List;

// Создание нового узла
Node *create_node(int value){
    Node *node = malloc(sizeof(Node));
    if (node == NULL) {
        return NULL;
    }
    node->value = value;
    node->prev = NULL;
    node->next = NULL;
    return node;
}

// Добавление в конец
void push_back(List *list, int value){
    Node *node = create_node(value);
    if (node == NULL) {
        return;
    }
    if (list->tail == NULL) {
        // Список пуст
        list->head = node;
        list->tail = node;
        return;
    }
    node->prev = list->tail;
    list->tail->next = node;
    list->tail = node;
}

// Вывод слева направо
void print_forward(const List *list){
    Node *current = list->head;
    while (current != NULL) {
        printf("%d ", current->value);
        current = current->next;
    }
    printf("\n");
}

// Вывод справа налево
void print_backward(const List *list){
    Node *current = list->tail;
    while (current != NULL) {
        printf("%d ", current->value);
        current = current->prev;
    }
    printf("\n");
}

// Удаление узла
void remove_node(List *list, Node *node){
    if (node == NULL) {
        return;
    }
    // Если есть предыдущий узел,
    // связываем его со следующим.
    if (node->prev != NULL) {
        node->prev->next = node->next;
    } else {
        // Удаляется head
        list->head = node->next;
    }
    // Если есть следующий узел,
    // связываем его с предыдущим.
    if (node->next != NULL) {
        node->next->prev = node->prev;
    } else {
        // Удаляется tail
        list->tail = node->prev;
    }
    free(node);
}

// Поиск узла
Node *find_node(const List *list, int value){
    Node *current = list->head;
    while (current != NULL) {
        if (current->value == value) {
            return current;
        }
        current = current->next;
    }
    return NULL;
}

// Освобождение списка
void free_list(List *list){
    Node *current = list->head;
    while (current != NULL) {
        Node *next = current->next;
        free(current);
        current = next;
    }
    list->head = NULL;
    list->tail = NULL;
}

int main(void){
    List list = {
        .head = NULL,
        .tail = NULL
    };

    push_back(&list, 10);
    push_back(&list, 20);
    push_back(&list, 30);
    push_back(&list, 40);

    printf("Forward:  ");
    print_forward(&list);
    
    // Удаление узла из середины
    //   находим узел 30
    Node *node = find_node(&list, 30);
    //   удаляем его
    remove_node(&list, node);

    printf("Backward: ");
    print_backward(&list);

    free_list(&list);

    return 0;
}

Пример на Rust. Алгоритм Floyd's Cycle Detection

Rust гарантирует memory safety но не гарантирует отсутствие memory leaks. Через Rc-циклы утечки памяти вполне возможны. Проблема возникает, если цикл образован именно strong reference count (Rc<T>).

Rust на этапе компиляции хорошо ловит проблемы с временем жизни ссылок, ownership и borrow rules, но Rc — это strong reference counting. Он просто считает, сколько strong ссылок существует на объект. Если A держит Rc на B, а B держит Rc на A, то счётчик ссылок у обоих никогда не станет нулём. Даже если внешние переменные уже исчезли, они всё ещё держат друг друга. Поэтому Rust не освобождает эту память автоматически.

Именно поэтому для обратных ссылок часто используют weak reference count (Weak<T>). Weak не увеличивает strong reference count, и цикл не удерживает объекты в памяти.

Но в Singly Linked List у каждого узла есть только ссылка next на следующий узел, обратной ссылки prev нет, поэтому обычному списку Weak не нужен. Weak понадобился бы, если бы была связь назад, например в doubly linked list, чтобы не получить цикл сильных Rc-ссылок (потому что strong Rc увеличивает счётчик владения, и если узлы держат друг друга через Rc, их strong_count никогда не станет 0, поэтому память не освободится).

use std::cell::RefCell;
use std::rc::Rc;

type Link = Option<Rc<RefCell<Node>>>;

#[derive(Debug)]
struct Node {
    value: char,
    next: Link,
}
impl Node {
    fn new(value: char) -> Rc<RefCell<Node>> {
        Rc::new(RefCell::new(Node {
            value,
            next: None,
        }))
    }
}
fn has_cycle(head: Link) -> bool {
    let mut slow = head.clone();
    let mut fast = head;

    loop {
        slow = match slow {
            Some(ref node) => node.borrow().next.clone(),
            None => return false,
        };
        fast = match fast {
            Some(ref node) => {
                let next = node.borrow().next.clone();

                match next {
                    Some(ref next_node) => next_node.borrow().next.clone(),
                    None => return false,
                }
            }
            None => return false,
        };
        match (&slow, &fast) {
            (Some(s), Some(f)) if Rc::ptr_eq(s, f) => {
                return true;
            }
            _ => {}
        }
    }
}
fn main() {
    let a = Node::new('A');
    let b = Node::new('B');
    let c = Node::new('C');
    let d = Node::new('D');

    // A -> B -> C -> D
    a.borrow_mut().next = Some(b.clone());
    b.borrow_mut().next = Some(c.clone());
    c.borrow_mut().next = Some(d.clone());

    println!(
        "Before. Cycle Detection: {}",
        has_cycle(Some(a.clone()))
    );

    // D -> B
    //
    // A -> B -> C -> D
    //      ^         |
    //      |_________|
    d.borrow_mut().next = Some(b.clone());

    println!(
        "After. Cycle Detection: {}",
        has_cycle(Some(a.clone()))
    );
}


Пример на Rust. Реализация Doubly Linked List

use std::cell::RefCell;
use std::rc::{Rc, Weak};

type Link = Option<Rc<RefCell<Node>>>;
type WeakLink = Option<Weak<RefCell<Node>>>;

#[derive(Debug)]
struct Node {
    value: i32,
    prev: WeakLink,
    next: Link,
}

#[derive(Debug)]
struct List {
    head: Link,
    tail: Link,
}
impl Node {
    fn new(value: i32) -> Rc<RefCell<Node>> {
        Rc::new(RefCell::new(Node {
            value,
            prev: None,
            next: None,
        }))
    }
}
impl List {
    fn new() -> Self {
        Self {
            head: None,
            tail: None,
        }
    }
    // Добавление в конец
    fn push_back(&mut self, value: i32) {
        let node = Node::new(value);
        match self.tail.take() {
            None => {
                // Список пуст
                self.head = Some(node.clone());
                self.tail = Some(node);
            }
            Some(old_tail) => {
                node.borrow_mut().prev = Some(Rc::downgrade(&old_tail));
                old_tail.borrow_mut().next = Some(node.clone());
                self.tail = Some(node);
            }
        }
    }
    // Вывод слева направо
    fn print_forward(&self) {
        let mut current = self.head.clone();
        while let Some(node) = current {
            print!("{} ", node.borrow().value);
            current = node.borrow().next.clone();
        }
        println!();
    }
    // Вывод справа налево
    fn print_backward(&self) {
        let mut current = self.tail.clone();
        while let Some(node) = current {
            print!("{} ", node.borrow().value);

            current = node
                .borrow()
                .prev
                .as_ref()
                .and_then(|prev| prev.upgrade());
        }
        println!();
    }
    // Поиск узла
    fn find_node(&self, value: i32) -> Link {
        let mut current = self.head.clone();
        while let Some(node) = current {
            if node.borrow().value == value {
                return Some(node);
            }
            current = node.borrow().next.clone();
        }
        None
    }
    // Удаление узла
    fn remove_node(&mut self, node: Rc<RefCell<Node>>) {
        let prev = node
            .borrow()
            .prev
            .as_ref()
            .and_then(|prev| prev.upgrade());

        let next = node.borrow().next.clone();
        // Обновляем предыдущий узел
        match &prev {
            Some(prev_node) => {
                prev_node.borrow_mut().next = next.clone();
            }
            None => {
                // Удаляем head
                self.head = next.clone();
            }
        }
        // Обновляем следующий узел
        match &next {
            Some(next_node) => {
                next_node.borrow_mut().prev =
                    prev.as_ref().map(Rc::downgrade);
            }
            None => {
                // Удаляем tail
                self.tail = prev.clone();
            }
        }
        // Отсоединяем сам узел
        node.borrow_mut().prev = None;
        node.borrow_mut().next = None;
    }
    // Очистка списка
    fn clear(&mut self) {
        self.head = None;
        self.tail = None;
    }
}
fn main() {
    let mut list = List::new();
    list.push_back(10);
    list.push_back(20);
    list.push_back(30);
    list.push_back(40);
    print!("Forward:  ");
    list.print_forward();
    // Удаление узла 30
    if let Some(node) = list.find_node(30) {
        list.remove_node(node);
    }
    print!("Backward: ");
    list.print_backward();
    list.clear();
}


Stack

Stack — структура данных, которая работает по принципу: LIFO — Last In, First Out т.е. последний добавленный элемент извлекается первым, так как добавление и удаление происходит в одно место - TOP списка. Для реализации на массиве TOP это конец массива, а для реализация через односвязный список TOP это первый элемент head.

Визуализация работы Stack

Stack ознакомление

Стек — это в первую очередь модель доступа к данным, а не конкретный способ хранения, он может быть реализован через:

  • Array / Dynamic Array
  • Singly Linked List

Сильные стороны

  • push и pop обычно выполняются за
  • Очень простая модель доступа к данным
  • Хорошо подходит для задач, где нужно отменять последние действия
  • Естественно поддерживает вложенность
  • Удобен для алгоритмов, где нужно временно запоминать предыдущие состояния
  • Хорошо подходит для обхода структур в глубину
  • При реализации через динамический массив имеет хорошую cache locality
  • Часто позволяет избежать рекурсии

Слабые стороны

Stack как ADT задаёт только правила доступа: push, pop, peek:

  • Ограниченный интерфейс доступа: основная работа идёт только с top элементом
  • Нет стандартной операции произвольного доступа или удаления из середины
  • Поиск по значению не является сильной стороной Stack и обычно требует
  • Порядок извлечения фиксирован как LIFO; если задача требует FIFO (элементы в порядке их поступления это уже Queue), абстракция Stack ей не соответствует

Сложность операций

ОперацияСреднееХудшееПочему
pushO(1)O(n)*resize динамического массива
popO(1)O(1)работа только с верхним элементом
peek / topO(1)O(1)верхний элемент уже известен
ПоискO(n)O(n)нужно просматривать элементы
Доступ к произвольному элементуO(n)**O(n)**стек логически этого не предоставляет
Проверка isEmptyO(1)O(1)достаточно проверить размер

* Для реализации через dynamic array. Амортизированная сложность push — O(1).

** Конкретная реализация через массив технически может позволять индексированный доступ, но если использовать структуру именно как Stack, такой доступ нарушает её абстракцию.

Память

Если Stack реализован через dynamic array: хорошая cache locality

Если через Linked List: не нужен resize

Т.е. свойства памяти зависят от реализации, а поведение LIFO остаётся тем же.

Когда использовать

  • Нужно обрабатывать элементы в обратном порядке их поступления
  • Нужна история последних действий
  • Нужно реализовать Undo (механизм отмены последнего действия)
  • Есть вложенные конструкции
  • Нужно проверять парные скобки
  • Нужно выполнять Depth-First Search
  • Нужно заменить рекурсивный алгоритм итеративным
  • Нужно хранить промежуточные состояния алгоритма
  • Нужно вычислять выражения или преобразовывать их форму
  • Нужно отслеживать контекст вызовов

Когда не использовать

  • Нужно обрабатывать элементы в порядке поступления — лучше Queue
  • Нужен доступ к элементам по индексу
  • Нужен поиск по ключу
  • Нужно удалять произвольные элементы
  • Нужно получать минимум/максимум без дополнительной структуры
  • Нужно часто обходить всю коллекцию
  • Порядок LIFO не соответствует логике задачи

Алгоритмы и задачи, связанные со Stack

Balanced Parentheses
Expression Evaluation
Infix → Postfix
Postfix Evaluation
Depth-First Search
Iterative Tree Traversal
Backtracking
Undo / Redo
Monotonic Stack
Next Greater Element
Previous Smaller Element
Browser History
Call Stack

Задачи

Насколько Stack подходит, где возникнут проблемы, какие его свойства используются:

  • LIFO — последний добавленный элемент извлекается первым
  • top — единственная основная точка доступа
  • push / pop — основные операции стека
  • restricted access — произвольный доступ логически запрещён
  • reverse order — стек естественно разворачивает порядок
  • nested structure — стек хорошо отражает вложенность
  • state history — стек хранит историю состояний
  • call stack — вызовы функций естественно образуют стек
  • explicit stack — собственный Stack может заменить рекурсию
  • stack overflow — слишком глубокий call stack может закончить доступную память
  • monotonic stack — стек, элементы которого поддерживаются в возрастающем или убывающем порядке
  • implementation independence — Stack можно реализовать через разные структуры данных

info

Главный вопрос: нужен ли задаче именно порядок Last In — First Out?

important

Stack / Queue / Deque в первую очередь описывают правила доступа к данным

Stack — это не «контейнер, где элементы лежат вертикально»

Stack — это ограничение доступа:

  • добавлять можно сверху
  • удалять можно сверху
  • смотреть тоже можно, но в первую очередь сверху

example

№1 Undo

Текстовый редактор хранит действия пользователя:

ввод "A"
ввод "B"
удалить символ
вставить "C"

Пользователь нажимает: Undo

Нужно отменить самое последнее действие.

Подходит ли Stack?

Да. Последнее выполненное действие должно быть отменено первым.

Это точно соответствует:

Last In → First Out

example

№2 обработка задач по порядку поступления

Сервер получает запросы:

Request A
Request B
Request C

Обрабатывать нужно строго в том порядке, в котором они пришли:

A → B → C
Подходит ли Stack?

Нет. Stack вернёт:

C → B → A

потому что работает по LIFO.

Здесь логика задачи соответствует Queue: FIFO — First In, First Out


example

№3 проверка скобок/тегов

Нужно проверить выражение:

{ [ (a + b) * c ] + d }

Корректно ли закрываются скобки?

Либо проверить корректность HTML/XML-подобных тегов

<a>
    <b>
        <c>
        </c>
    </b>
</a>
Почему здесь подходит Stack?

Стек здесь нужен потому, что закрывающий тег/скобка, должна соответствовать последней незакрытой открывающей тегу/скобке. Это как раз LIFO.

По мере заполнения стэка у нас на вершине всегда последняя скобка, как только мы обнаруживаем закрытую скобку мы тут же сравниваем что сечас в стеке т.е. какая была последняя скобка, если последняя скобка была того же типа что и обнаруженная закрывающая скобка значит ошибки нет, иначе несоответвие порядку. После успешного совпадения мы делаем pop, чтобы убрать соответствующую открытую скобку из стека.


example

№4 обратный порядок

Получена последовательность: A B C D E

Нужно вывести: E D C B A

Подходит ли Stack?

Да. Добавляем:

push A
push B
push C
push D
push E

Затем последовательно выполняем pop:

E
D
C
B
A

Stack естественным образом переворачивает порядок элементов.


example

№5 доступ к 500-му элементу

В Stack находится миллион элементов.

Программа постоянно выполняет запрос: получить элемент №500000

Подходит ли Stack?

Нет. Stack предназначен для работы с: top, а не с произвольной позицией.

Даже если конкретная реализация использует массив и технически может обратиться по индексу, это уже использование массива, а не абстракции Stack.


example

№6 вызовы функций

Программа выполняет:

main()
  → functionA()
      → functionB()
          → functionC()

После завершения functionC нужно вернуться в functionB, затем в functionA, затем в main.

Почему здесь естественно возникает Stack?

Каждый новый вызов функции добавляет frame:

functionC   ← top
functionB
functionA
main

Когда функция завершается: pop, удаляется последний вызов.

Это и есть call stack.

Но если ф-ция с глубокой рекурсией. Каждый рекурсивный вызов создаёт новый stack frame и память выделенная под call stack может закончиться, тогда произойдет исключение stack overflow. В такой ситуации рекурсивный алгоритм иногда заменяют на собственный Stack, размещённый в heap.

Проверить склько места выделнно ОС под stack frame:

ulimit -s
# 8192 KiB
extern crate libc;
use libc::{getrlimit, rlimit, RLIMIT_STACK};

fn main() {
    let mut limit = rlimit {
        rlim_cur: 0,
        rlim_max: 0,
    };

    unsafe {
        getrlimit(RLIMIT_STACK, &mut limit);
    }

    println!("Stack limit: {} KiB", limit.rlim_cur / 1024);
}

example

№7 DFS без рекурсии

Нужно обойти граф в глубину.

Обычно алгоритм пишут рекурсивно:

visit(node)
    visit(child)
Можно ли сделать это без рекурсии?

Да. Создаём Stack вручную.

Stack хранит вершины, к которым алгоритм должен вернуться.

Это explicit stack вместо call stack.


example

№8 история браузера

Пользователь открывает:

google.com
github.com
rust-lang.org
stackoverflow.com

После этого несколько раз нажимает:

Back
Подходит ли один Stack?

Для простого движения назад — да.

История:

stackoverflow.com ← top
rust-lang.org
github.com
google.com

Нажатие Back снимает верхний элемент.

Но если нужны одновременно:

Back
Forward

обычно используют два Stack:

back_stack
forward_stack

example

№9 поиск по ID

Stack содержит 10 миллионов объектов.

Основная операция: найти объект с id = 817234

Подходит ли Stack?

Нет. Stack не предоставляет поиска по ключу.

Для поиска придётся просматривать элементы:

Если поиск по id — главная операция, лучше Hash Table.


example

№10 Stack через Dynamic Array

Stack реализован через Dynamic Array.

Capacity уже заполнена:

[A][B][C][D]
           ↑
          top

Выполняется добавление нового элемента: push(E)

Всегда ли push O(1)?

Нет. Конкретный push может стоить ,так как при геометрическом увеличении capacity необходимо учитывать amortized

Если свободной capacity нет, dynamic array должен:

  1. выделить новый участок памяти
  2. скопировать старые элементы
  3. добавить новый элемент

example

№11 минимальный элемент

В Stack лежат числа, нужно поддерживать операции за :

push
pop
getMin
Обычного Stack достаточно?

Можно использовать второй Stack:

data_stack
min_stack

min_stack хранит текущие минимумы.

Например:

push 8
min = 8

push 5
min = 5

push 7
min = 5

push 2
min = 2

Получаем Min Stack.

Это пример того, как дополнительная структура позволяет расширить возможности Stack.


example

№12 последовательность температур

Есть температуры по дням:

День:         0   1   2   3   4   5   6   7   
Температура: 73  74  75  71  69  72  76  73

Для каждого дня нужно определить, через сколько дней после него появится более высокая температура. Например для первого дня (индекс 0) - уже на следующем дне теплее т.е. для него значение будет равно 1, как и для второго дня. Для третьего дня - через 4 дня станет теплее (76 градусов). Для 7 и 8-го дня еще нет такого дня с более темлой температурой, поэтому сохраняем 0. И все эти результаты мы должны хранить [1,1,4,...,0,0]

Можно ли решить это через Stack?

Да — через Monotonic Stack.

В Stack можно хранить индексы дней, для которых более высокая температура ещё не найдена.

Индексы мы сохраняем чтобы знать какой это день, тогда мы сможем его вычесть из индекса дня с более высокой температурой и так получи количество дней до нее.

Так каждый элемент добавляется и удаляется из стека максимум один раз.

Общая сложность:

Это классический пример Monotonic Stack.


example

№13 Backtracking

Алгоритм исследует варианты:

A
├── B
│   ├── D
│   └── E
└── C

Нужно пойти глубоко по одному пути, а если он не подходит — вернуться назад.

Где здесь Stack?

Stack хранит предыдущие состояния или точки возврата.

Например:

A
A → B
A → B → D

Если D не подходит pop D и возвращаемся к B.

Именно поэтому Stack часто связан с:

DFS
Backtracking
Undo

Все эти задачи используют одну идею:

последнее сохранённое состояние обрабатывается первым



Упражнения

Реализация логики - обратный порядок слова

#![allow(unused)]

use stack::Stack;
pub mod stack{
    pub struct Stack<T> {
        items: Vec<T>,
    }
    impl<T> Stack<T> {
        pub fn new() -> Self {
            Self {
                items: Vec::new(),
            }
        }
        pub fn push(&mut self, value: T) {
            self.items.push(value);
        }
        pub fn pop(&mut self) -> Option<T> {
            self.items.pop()
        }
        pub fn peek(&self) -> Option<&T> {
            self.items.last()
        }
        pub fn is_empty(&self) -> bool {
            self.items.is_empty()
        }
        pub fn len(&self) -> usize {
            self.items.len()
        }
    }
}
 
fn reverse_word(word: &str) -> String {
    let mut stack = Stack::new();
    for ch in word.chars() {
        stack.push(ch);
    }
    let mut result = String::new();
    while let Some(ch) = stack.pop() {
        result.push(ch);
    }
    result
}

fn main() {
    let word = "hello";
    let reversed = reverse_word(word);
    println!("{}", reversed);
}
 

Реализация логики возврат из ф-ций

use stack::Stack;
pub mod stack{
    pub struct Stack<T> {
        items: Vec<T>,
    }
    impl<T> Stack<T> {
        pub fn new() -> Self {
            Self {
                items: Vec::new(),
            }
        }
        pub fn push(&mut self, value: T) {
            self.items.push(value);
        }
        pub fn pop(&mut self) -> Option<T> {
            self.items.pop()
        }
        pub fn peek(&self) -> Option<&T> {
            self.items.last()
        }
        pub fn is_empty(&self) -> bool {
            self.items.is_empty()
        }
        pub fn len(&self) -> usize {
            self.items.len()
        }
    }
}

#[derive(Debug)]
enum Function {
    Main,
    A,
    B,
    C,
}

#[derive(Debug)]
struct Frame {
    function: Function,
}

fn main() {
    let mut call_stack: Stack<Frame> = Stack::new();

    // main
    call_stack.push(Frame { function: Function::Main });

    // main -> functionA
    call_stack.push(Frame { function: Function::A });

    // main -> functionA -> functionB
    call_stack.push(Frame { function: Function::B });

    // main -> functionA -> functionB -> functionC
    call_stack.push(Frame { function: Function::C });

    println!("Глубина стека: {}", call_stack.len());
    println!("Текущая функция: {:?}", call_stack.peek());
    while let Some(frame) = call_stack.pop() {
        println!("Завершилась {:?}", frame.function);
        match call_stack.peek() {
            Some(previous) => {
                println!("Возвращаемся в {:?}", previous.function);
            }
            None => {
                println!("Программа завершена");
            }
        }
        println!();
    }
}

Реализация логики проверки скобок и тегов

use stack::Stack;
pub mod stack{
    pub struct Stack<T> {
        items: Vec<T>,
    }
    impl<T> Stack<T> {
        pub fn new() -> Self {
            Self {
                items: Vec::new(),
            }
        }
        pub fn push(&mut self, value: T) {
            self.items.push(value);
        }
        pub fn pop(&mut self) -> Option<T> {
            self.items.pop()
        }
        pub fn peek(&self) -> Option<&T> {
            self.items.last()
        }
        pub fn is_empty(&self) -> bool {
            self.items.is_empty()
        }
        pub fn len(&self) -> usize {
            self.items.len()
        }
    }
}
fn is_brackets_valid(expression: &str) -> bool {
    let mut stack = Stack::new();

    for ch in expression.chars() {
        match ch {
            '(' | '[' | '{' => {
            // при обнаружении открывающей скобки мы просто добавляем ее
                stack.push(ch);
            }
            ')' | ']' | '}' => {
            // при обнаружении закрывающей скобки мы сравниваем предыдущую, 
            //она должна быть того же типа что и закрывающая но открывающая 
                let Some(open) = stack.pop() else {
                    return false;
                };
                let matches = match (open, ch) {
                    ('(', ')') => true,
                    ('[', ']') => true,
                    ('{', '}') => true,
                    _ => false,
                };
                if !matches {
                    return false;
                }
            }
            _ => {}
        }
    }
    stack.is_empty()
}
fn is_tags_valid(input: &str) -> bool {
    let mut stack = Stack::new();

    for line in input.lines() {
        let tag = line.trim();

        // открывающий тег
        if tag.starts_with('<')
            && !tag.starts_with("</")
            && tag.ends_with('>')
        {
            let name = tag
                .trim_start_matches('<')
                .trim_end_matches('>');

            stack.push(name.to_string());
        }

        // закрывающий тег
        else if tag.starts_with("</") && tag.ends_with('>') {
            let name = tag
                .trim_start_matches("</")
                .trim_end_matches('>');

            let Some(open) = stack.pop() else {
                return false;
            };

            if open != name {
                return false;
            }
        }
    }
    stack.is_empty()
}
fn main() {
    let mut stack = Stack::new();
    stack.push(10);
    stack.push(20);
    stack.push(30);
    while !stack.is_empty() {
        println!("top:{:?}", stack.peek().unwrap());
        stack.pop();
    }
 
    //-------------------------------------------------
    // Expression check
    let expression = "{[ (a+b) * c ] + d }";
    println!("Expression check: {}", is_brackets_valid(expression));
    
    let expression = "{[ (a+b) * c + d }";
    println!("Expression check: {}", is_brackets_valid(expression));
    //-------------------------------------------------
    // Tag check
        let html = r#"
<a>
    <b>
        <c>
        </c>
    </b>
</a>
"#;

    println!("Tag check:{}", is_tags_valid(html));
}

Реализация логики Back/Forward посещенных сайтов

Для Back/Forward удобно использовать два стека и отдельно хранить текущую страницу.

use stack::Stack;
pub mod stack{
    pub struct Stack<T> {
        items: Vec<T>,
    }
    impl<T> Stack<T> {
        pub fn new() -> Self {
            Self {
                items: Vec::new(),
            }
        }
        pub fn push(&mut self, value: T) {
            self.items.push(value);
        }
        pub fn pop(&mut self) -> Option<T> {
            self.items.pop()
        }
        pub fn peek(&self) -> Option<&T> {
            self.items.last()
        }
        pub fn is_empty(&self) -> bool {
            self.items.is_empty()
        }
        pub fn len(&self) -> usize {
            self.items.len()
        }
    }
}
  
struct BrowserHistory {
    back_stack: Stack<String>,
    forward_stack: Stack<String>,
    current: String,
}

impl BrowserHistory {
    fn new(start_page: &str) -> Self {
        Self {
            back_stack: Stack::new(),
            forward_stack: Stack::new(),
            current: start_page.to_string(),
        }
    }

    fn visit(&mut self, page: &str) {
        // Текущая страница становится частью истории Back
        self.back_stack.push(self.current.clone());

        // Переходим на новую страницу
        self.current = page.to_string();

        // После нового перехода история Forward больше неактуальна
        //, потому что пользователь пошёл по новой ветке истории. 
        // Очишаем весь стек переходов Forward
        while !self.forward_stack.is_empty() {
            self.forward_stack.pop();
        }
    }

    fn back(&mut self) {
        let Some(previous) = self.back_stack.pop() else {
            return;
        };

        // Текущую страницу сохраняем для Forward
        self.forward_stack.push(self.current.clone());

        self.current = previous;
    }

    fn forward(&mut self) {
        let Some(next) = self.forward_stack.pop() else {
            return;
        };

        // Текущая страница снова становится частью Back
        self.back_stack.push(self.current.clone());

        self.current = next;
    }

    fn current(&self) -> &str {
        &self.current
    }
}
fn main() {
    // google.com -> github.com -> rust-lang.org -> stackoverflow.com
    let mut browser = BrowserHistory::new("google.com");
    browser.visit("github.com");
    browser.visit("rust-lang.org");
    browser.visit("stackoverflow.com");

    println!("Current: {}", browser.current());// stackoverflow.com
    
    browser.back();
    println!("Back: {}", browser.current());// rust-lang.org
    
    browser.back();
    println!("Back: {}", browser.current());// github.com
    
    browser.forward();
    println!("Forward: {}", browser.current());// rust-lang.org
    
}

Реализация логики сохранения минимума

Что бы хранить текущий минимум того что хранится в стеке нужен всторой стек, так как при удалении элемента со стека мы не знаем какой сейчас минимум в оставшемся стеке есть.

#![allow(unused)]

use stack::Stack;
pub mod stack{
    pub struct Stack<T> {
        items: Vec<T>,
    }
    impl<T> Stack<T> {
        pub fn new() -> Self {
            Self {
                items: Vec::new(),
            }
        }
        pub fn push(&mut self, value: T) {
            self.items.push(value);
        }
        pub fn pop(&mut self) -> Option<T> {
            self.items.pop()
        }
        pub fn peek(&self) -> Option<&T> {
            self.items.last()
        }
        pub fn is_empty(&self) -> bool {
            self.items.is_empty()
        }
        pub fn len(&self) -> usize {
            self.items.len()
        }
    }
}

struct MinStack {
    data_stack: Stack<i32>,// все значения
    min_stack: Stack<i32>,// текущие минимумы
}
impl MinStack {
    fn new() -> Self {
        Self {
            data_stack: Stack::new(),
            min_stack: Stack::new(),
        }
    }
    fn push(&mut self, value: i32) {
        self.data_stack.push(value);
        // в min_stack попадет элемент если он меньше чем предыдущий или равен ему
        match self.min_stack.peek() {
            Some(&current_min) if value > current_min => {}
            _ => self.min_stack.push(value),
        }
    }
    fn pop(&mut self) -> Option<i32> {
        let value = self.data_stack.pop()?;

        if self.min_stack.peek() == Some(&value) {
            self.min_stack.pop();
        }

        Some(value)
    }
    fn peek(&self) -> Option<&i32> {
        self.data_stack.peek()
    }
    fn get_min(&self) -> Option<&i32> {
        self.min_stack.peek()
    }
}

fn main() {
    let mut stack = MinStack::new();

    stack.push(8);
    stack.push(5);
    stack.push(7);// это не попадет в min_stack
    stack.push(5);
    stack.push(2);

    while let Some(_) = stack.peek(){
        stack.pop();
        println!("min = {:?}", stack.get_min());// 5 5 5 8 None
    }
}

Реализация логики Monotonic Stack

Есть температуры по дням:

День:         0   1   2   3   4   5   6   7   
Температура: 73  74  75  71  69  72  76  73

Для каждого дня нужно определить, через сколько дней после него появится более высокая температура. Например для первого дня (индекс 0) - уже на следующем дне теплее т.е. для него значение будет равно 1, как и для второго дня. Для третьего дня - через 4 дня станет теплее (76 градусов). Для 7 и 8-го дня еще нет такого дня с более темлой температурой, поэтому сохраняем 0. И все эти результаты мы должны хранить [1,1,4,...,0,0]

В Stack можно хранить индексы дней, для которых более высокая температура ещё не найдена.

Индексы мы сохраняем чтобы знать какой это день, тогда мы сможем его вычесть из индекса дня с более высокой температурой и так получи количество дней до нее.

#![allow(unused)]

use stack::Stack;
pub mod stack{
    pub struct Stack<T> {
        items: Vec<T>,
    }
    impl<T> Stack<T> {
        pub fn new() -> Self {
            Self {
                items: Vec::new(),
            }
        }
        pub fn push(&mut self, value: T) {
            self.items.push(value);
        }
        pub fn pop(&mut self) -> Option<T> {
            self.items.pop()
        }
        pub fn peek(&self) -> Option<&T> {
            self.items.last()
        }
        pub fn is_empty(&self) -> bool {
            self.items.is_empty()
        }
        pub fn len(&self) -> usize {
            self.items.len()
        }
    }
}
 
fn daily_temperatures(temperatures: &[i32]) -> Vec<usize> {
    let mut result = vec![0; temperatures.len()];
    let mut stack: Stack<usize> = Stack::new();

    for i in 0..temperatures.len() {
        while let Some(&last_index) = stack.peek() {
            if temperatures[i] <= temperatures[last_index] {
                break;
            }
            let previous_index = stack.pop().unwrap();
            result[previous_index] = i - previous_index;
        }
        stack.push(i);
    }

    result
}

fn main() {
    let temperatures = vec![73, 74, 75, 71, 69, 72, 76, 73];

    let result = daily_temperatures(&temperatures);

    println!("{:?}", result);
}

Пример обход графа рекурсивно и итеративно используя Stack

A
├── B
│   ├── D
│   └── E
└── C
    └── F
 
use std::collections::{HashMap, HashSet};

fn build_graph() -> HashMap<&'static str, Vec<&'static str>> {
    HashMap::from([
        ("A", vec!["B", "C"]),
        ("B", vec!["D", "E"]),
        ("C", vec!["F"]),
        ("D", vec![]),
        ("E", vec![]),
        ("F", vec![]),
    ])
}


fn dfs_recursive(
    graph: &HashMap<&str, Vec<&str>>,
    node: &str,
    visited: &mut HashSet<String>,
) {
    if visited.contains(node) {
        return;
    }

    visited.insert(node.to_string());

    println!("{}", node);

    if let Some(neighbors) = graph.get(node) {
        for &neighbor in neighbors {
            dfs_recursive(graph, neighbor, visited);
        }
    }
}


use stack::Stack;
pub mod stack{
    pub struct Stack<T> {
        items: Vec<T>,
    }
    impl<T> Stack<T> {
        pub fn new() -> Self {
            Self {
                items: Vec::new(),
            }
        }
        pub fn push(&mut self, value: T) {
            self.items.push(value);
        }
        pub fn pop(&mut self) -> Option<T> {
            self.items.pop()
        }
        pub fn peek(&self) -> Option<&T> {
            self.items.last()
        }
        pub fn is_empty(&self) -> bool {
            self.items.is_empty()
        }
        pub fn len(&self) -> usize {
            self.items.len()
        }
    }
}
// Стартуем с головы, добавляем ее в stack
// В цикле просто достаем из стека узел проверяем посещали ли мы его ранее иначе печатаем, 
// далее смотрим его детей и добавляем их в стек
fn dfs_iterative(
    graph: &HashMap<&str, Vec<&str>>,
    start: &str,
) {
    let mut visited = HashSet::new();
    let mut stack = Stack::new();

    stack.push(start.to_string());

    while let Some(node) = stack.pop() {
        if visited.contains(&node) {
            continue;
        }

        visited.insert(node.clone());

        println!("{}", node);

        if let Some(neighbors) = graph.get(node.as_str()) {
            for &neighbor in neighbors.iter().rev() {
                stack.push(neighbor.to_string());
            }
        }
    }
}

fn main() {
    let graph = HashMap::from([
        ("A", vec!["B", "C"]),
        ("B", vec!["D", "E"]),
        ("C", vec!["F"]),
        ("D", vec![]),
        ("E", vec![]),
        ("F", vec![]),
    ]);

    let mut visited = HashSet::new();
    println!("\nUse recursive:");
    dfs_recursive(&graph, "A", &mut visited);
    println!("\nUse iterative (Stack):");
    dfs_iterative(&graph, "A");
}

Реализация Stack на языке C

example from ideone.com

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

typedef struct {
    int *items;
    size_t len;
    size_t capacity;
} Stack;

Stack stack_new(void)
{
    Stack stack = {
        .items = NULL,
        .len = 0,
        .capacity = 0
    };

    return stack;
}

void stack_push(Stack *stack, int value)
{
    if (stack->len == stack->capacity) {
        size_t new_capacity = stack->capacity == 0
            ? 4
            : stack->capacity * 2;

        int *new_items = realloc(
            stack->items,
            new_capacity * sizeof(int)
        );

        if (new_items == NULL) {
            exit(EXIT_FAILURE);
        }

        stack->items = new_items;
        stack->capacity = new_capacity;
    }

    stack->items[stack->len] = value;
    stack->len++;
}

bool stack_pop(Stack *stack, int *value)
{
    if (stack->len == 0) {
        return false;
    }

    stack->len--;
    *value = stack->items[stack->len];

    return true;
}

bool stack_peek(const Stack *stack, int *value)
{
    if (stack->len == 0) {
        return false;
    }

    *value = stack->items[stack->len - 1];

    return true;
}

bool stack_is_empty(const Stack *stack)
{
    return stack->len == 0;
}

size_t stack_len(const Stack *stack)
{
    return stack->len;
}

void stack_free(Stack *stack)
{
    free(stack->items);

    stack->items = NULL;
    stack->len = 0;
    stack->capacity = 0;
}

int main(void)
{
    Stack stack = stack_new();

    stack_push(&stack, 10);
    stack_push(&stack, 20);
    stack_push(&stack, 30);

    printf("len = %zu\n", stack_len(&stack));

    int value;

    if (stack_peek(&stack, &value)) {
        printf("peek = %d\n", value);
    }

    if (stack_pop(&stack, &value)) {
        printf("pop = %d\n", value);
    }

    if (stack_pop(&stack, &value)) {
        printf("pop = %d\n", value);
    }

    printf("len = %zu\n", stack_len(&stack));
    printf("empty = %s\n",
           stack_is_empty(&stack) ? "true" : "false");

    stack_free(&stack);

    return 0;
}


Queue / Deque

Queue — очередь, структура данных, которая работает по принципу: FIFO — First In, First Out

Визуализация работы Queue

Первый добавленный элемент извлекается первым, т.е. новые элементы добавляются в конец, а удаляются из начала.

Основные операции Queue:

  • enqueue — добавить элемент в конец
  • dequeue — удалить элемент из начала
  • peek — посмотреть первый элемент
Queue / Deque ознакомление

Если реализовать Queue через массив, то при удалении из начала мы получим сдвиг всех элементов, это дорогая операция . Именно поэтому эффективная реализация использует кольцевой буфер (Ring buffer - это массив с укзателями на начало и конец очереди head и tail т.е. они могут указывать на элементы массива в его середине), тогда удаление станет быстрой операцией .

Deque (Double-Ended Queue) — это очередь, в которой можно добавлять и удалять элементы с обоих концов:

  • push_front
  • push_back
  • pop_front
  • pop_back

То есть Deque умеет работать и как Queue, и как Stack.

По аналогии со стеком, очередь так же — это в первую очередь модель доступа к данным, а не конкретный способ хранения, она может быть реализована через:

  • Ring Buffer
  • Doubly Linked List (но памяти занимает больше и плохая cache locality)

Ring Buffer

Одна из важных особенностей динамического Ring Buffer, когда head и tail уже завернулись через конец массива: при resize он «распрямляет» кольцо в обычный последовательный массив, нужно перестроить расположение элементов так, чтобы они снова шли подряд от head. Мы копируем элементы не в физическом порядке старого массива, а в логическом порядке очереди.

Для Queue, добавление в конец куда указывает tail, и удаление из начала куда указывает head

Простой случая выделения большей емкости

Ring Buffer: capacity 4 
len = 0
+----+----+----+----+
|  0 |  0 |  0 |  0 |
+----+----+----+----+
 head
 tail

1. Operation: enqueue 1 (т.е. добавление)
len = 1
+----+----+----+----+
|  1 |  0 |  0 |  0 |
+----+----+----+----+
 head tail

2. Operation: enqueue 2
len = 2
+----+----+----+----+
|  1 |  2 |  0 |  0 |
+----+----+----+----+
 head      tail

3. Operation: enqueue 3
len = 3
+----+----+----+----+
|  1 |  2 |  3 |  0 |
+----+----+----+----+
 head           tail

4. Operation: enqueue 4
len = 4
+----+----+----+----+
|  1 |  2 |  3 |  4 |
+----+----+----+----+
 head           

5. Operation: enqueue 5
Нам нужно увеличить capacity +4, так как уже нет места
Выделяем новый массив и переносим логическую последовательность

capacity 8  
len = 5
+----+----+----+----+----+----+----+----+
|  1 |  2 |  3 |  4 |  5 |  0 |  0 |  0 |
+----+----+----+----+----+----+----+----+
 head                     tail


Случай выделения большей емкости с необходимостью «распрямления» кольца

Ring Buffer: capacity 4 
len = 3
+----+----+----+----+
|  1 |  2 |  3 |  0 |
+----+----+----+----+
 head           tail

1. Operation: dequeue (т.е. удаление)
len = 2
+----+----+----+----+
| 1* |  2 |  3 |  0 |
+----+----+----+----+
      head      tail     

1* что бы избежать сдвига элементов мы его не удаляем, т.е. удаляемые элементы остаются физически в массиве, 
мы их просто перезаписываем новыми значениями, когда до них дойдет tail 

2. Operation: enqueue 4 (т.е. добавление)
len = 3
+----+----+----+----+
| 1* |  2 |  3 |  4 |
+----+----+----+----+
 tail head        

т.е. tail переместился в начало массива, на свободное место помеченное как удаленное

3. Operation: dequeue (т.е. удаление)
len = 2
+----+----+----+----+
| 1* | 2* |  3 |  4 |
+----+----+----+----+
 tail      head         


3. Operation: enqueue 5 (т.е. добавление)
len = 3
+----+----+----+----+
| 5  | 2* |  3 |  4 |
+----+----+----+----+
      tail head  

4. Operation: enqueue 6 (т.е. добавление)
len = 4
+----+----+----+----+
| 5  | 6  |  3 |  4 |
+----+----+----+----+
           head  
закольцевались!

5. Operation: enqueue 7 (т.е. добавление)
Логический порядок сейчас такой, начиная с head: 3 -> 4 -> 5 -> 6 
Но tail уже некуда двигаться, чтобы добавить новый элемент и к тому же конец очереди находится в середине массива!
Мы не можем просто выделить новый массив и скопировать туда текущий заполненный массив, 
 так как нам по прежнему некуда будет продолжать очередь.
Поэтому мы не копируем массив, а согласно порядку очереди добавляем элементы в новый массив, 
 так чтобы последний элемент был последним в новом массиве.
Т.е. мы разворачиваем в линию образовавшееся кольцо нашей очереди в массиве.


capacity 8 
len = 4
+----+----+----+----+----+----+----+----+
|  3 |  4 |  5 |  6 |  0 |  0 |  0 |  0 |
+----+----+----+----+----+----+----+----+
 head                tail

и добавляем новый элемент
len = 5
+----+----+----+----+----+----+----+----+
|  3 |  4 |  5 |  6 |  7 |  0 |  0 |  0 |
+----+----+----+----+----+----+----+----+
 head                     tail


Сильные стороны Queue

  • Быстрое добавление в конец
  • Быстрое удаление из начала
  • Хорошо подходит для обработки задач в порядке поступления
  • Удобна для BFS (для графа поиск в ширину - обрабатывает вершины в том порядке, в котором они были обнаружены)
  • Удобна для буферизации данных
  • Хорошо подходит для producer/consumer сценариев
    • Producer создаёт задачи/данные и кладёт их в очередь
    • Consumer забирает их в том порядке, в котором они поступили
  • Позволяет ограничить обработку старых и новых событий по порядку

Сильные стороны Deque

  • Добавление и удаление с обоих концов за
  • Может работать как Queue
  • Может работать как Stack
  • Подходит для Sliding Window (скользящее окно)
  • Хорошо подходит для Monotonic Queue (очередь с дополнительным правилом: элементы внутри поддерживаются в монотонном порядке - например, от большего к меньшему)

Слабые стороны Queue/Deque

  • Deque более сложная структура, чем Queue
  • Не предназначена для произвольного доступа, работает с концами
  • Не подходит для произвольного удаления из середины (особенно реализация на обычном массиве)
  • Поиск по значению обычно

Сложность операций Queue

ОперацияСреднееХудшееПочему
enqueueO(1)O(1)*добавление в конец
dequeueO(1)O(1)удаление из начала
peekO(1)O(1)начало очереди известно
поискO(n)O(n)последовательный просмотр
isEmptyO(1)O(1)проверка размера

* При реализации через динамический массив возможен resize, тогда отдельный enqueue может быть , но амортизированно .

Сложность операций Deque

ОперацияСреднееХудшее
push_frontO(1)O(1)
push_backO(1)O(1)
pop_frontO(1)O(1)
pop_backO(1)O(1)
peek_frontO(1)O(1)
peek_backO(1)O(1)
поискO(n)O(n)

Память

Queue и Deque — это в первую очередь абстракции поведения.

При реализации через Ring Buffer, после удаления начала не нужно сдвигать элементы, индексы просто двигаются по кругу.

Когда использовать Queue

  • Нужно реализовать очередь задач
  • Обработка и буферизация потоков данных в порядке поступления (FIFO)
  • Есть producer/consumer модель
  • Нужен BFS
  • Нужно распределять задания между воркерами

Когда использовать Deque

  • Нужно работать с обоими концами последовательности
  • Нужно реализовать Stack и Queue одной структурой
  • Нужен Sliding Window
  • Нужна Monotonic Queue
  • Нужно быстро удалять устаревшие элементы слева и добавлять новые справа
  • Нужно выполнять BFS с разными приоритетами типа 0-1 BFS

Когда не использовать Queue/Deque

  • Нужен быстрый поиск по ключу
  • Нужен частый доступ к произвольному индексу
  • Нужны частые операции в середине структуры
  • Нужно хранить данные отсортированными
  • Нужен LIFO (тогда Stack проще), а не FIFO

Алгоритмы и задачи, связанные с Queue

Breadth-First Search
Level Order Traversal
Producer / Consumer
Task Scheduling
Message Queue
Ring Buffer
Sliding Window
Monotonic Queue
Sliding Window Maximum
0-1 BFS
Round Robin

Задачи

Свойства очереди:

  • FIFO — первый вошёл, первый вышел
  • front — начало очереди
  • back — конец очереди
  • enqueue / dequeue — базовые операции Queue
  • double-ended access — Deque работает с обоими концами
  • ring buffer — эффективная реализация очереди без сдвигов
  • no shifting — правильная Queue не должна каждый раз сдвигать массив
  • bounded queue — очередь может иметь фиксированную ёмкость
  • producer / consumer — один добавляет, другой извлекает
  • BFS — очередь хранит вершины по слоям
  • sliding window — Deque удобно хранит только актуальные элементы окна
  • monotonic deque — Deque может поддерживать возрастающий/убывающий порядок

info

Главный вопрос: в каком порядке данные должны покидать структуру?


example

№1 обработка запросов в порядке поступления

Сервер получает запросы:

A
B
C
D

Обрабатывать их нужно строго в порядке поступления.

Подходит ли Queue?

Да. Первый пришедший запрос будет обработан первым. Queue обеспечивает FIFO: A → B → C → D

Если нужен порядок LIFO т.е. наоборот D → C → B → A тогда нужен Stack


example

№2 очередь через обычный массив

Есть массив: arr[A B C D]

Удаление происходит из начала: arr[0]

В чём проблема?

После удаления A, происходит сдвиг [B][C][D][_], а это дорогая операция


example

№3 BFS

Есть граф:

        A
      /   \
     B     C
    / \     \
   D   E     F

Нужно обходить граф по уровням:

сначала вершину:
A

потом все вершины на расстоянии 1 ребро от A:
B C 

потом вершины на расстоянии 2 ребра:
D E F
Почему здесь Queue?

BFS использует Queue потому, что вершины, найденные раньше, должны быть обработаны раньше.

Т.е. вершины обрабатываются в порядке обнаружения.

Это и даёт обход по уровням.


example

№4 producer / consumer

Один поток создаёт задачи:

Task1
Task2
Task3

Другой поток их выполняет.

Почему Queue естественна?

Producer добавляет задачу: enqueue(task)

Consumer забирает задачу: dequeue()

Задачи обрабатываются в том порядке, в котором поступили т.е. порядок FIFO.

На практике между потоками понадобится синхронизация. Потому что producer и consumer могут одновременно обращаться к одной и той же Queue.


example

№5 очередь печати

Пользователи отправляют документы на принтер:

doc1
doc2
doc3
Подходит ли Queue?

Да. Первый отправленный документ обычно должен печататься первым.

Это классический FIFO.


example

№6 доступ к элементу

В Queue миллион элементов.

Очень часто нужно: получить элемент №500000

Подходит ли Queue?

Нет. Queue предоставляет в основном:

front
back

Если произвольный доступ — основная операция, лучше использовать другую структуру.


example

№7 Deque как Stack и Queue

Есть Deque.

Можно ли использовать его как Stack и как Queue?

Да. Как Stack например только через правый конец:

push_back
pop_back

Получаем LIFO.

Как Queue, например:

push_back
pop_front

Получаем FIFO.


example

№8 Sliding Window

Есть массив: arr[1 3 -1 -3 5 3 6 7]

Размер окна:

k = 3

Окна:

[1 3 -1]
  [3 -1 -3]
    [-1 -3 5]
...

Нужно быстро находить максимум в каждом окне.

Почему здесь нужен Deque?

Deque позволяет:

  • добавлять новый элемент справа
  • удалять устаревшие элементы слева
  • удалять справа элементы, которые уже не могут быть максимумом

Так можно поддерживать только полезных кандидатов на максимум.

Это Monotonic Deque.


example

№9 Monotonic Queue

Пусть текущий Deque хранит значения:

9 7 5

Приходит новое значение:

8
Что происходит?

Значения меньше 8 справа больше не нужны как кандидаты на максимум.

Удаляем:

5
7

Получаем:

9

Добавляем 8:

9 8

Deque остаётся монотонно убывающим.


example

№10 ограниченный буфер

Есть устройство, которое может хранить только последние 1000 событий.

Приходит 1001-е событие.

Подходит ли Queue / Deque?

Да. Можно использовать bounded queue.

Если буфер заполнен:

pop_front()
push_back(new_event)

Самое старое событие удаляется, новое добавляется.


example

№11 последние N элементов

Нужно всегда хранить последние 5 запросов пользователя.

Приходят:

A B C D E F G
Как использовать Deque?

Добавляем справа:

push_back

Если размер > 5:

pop_front

В итоге останется:

C D E F G

example

№12 задача с двумя концами

Есть последовательность задач.

Иногда нужно взять самую старую: pop_front, а иногда самую новую: pop_back

Что использовать?

Использовать Deque. Обычная Queue позволяет эффективно работать только с FIFO.

Deque предоставляет оба конца.


example

№13 0-1 BFS

В графе веса рёбер только:

0
1

Если переход имеет вес 0, вершину нужно обработать раньше.

Если вес 1 — позже.

Почему подходит Deque?

Можно делать:

weight = 0 → push_front
weight = 1 → push_back

Таким образом более дешёвые переходы автоматически получают приоритет.

Это алгоритм 0-1 BFS.


example

№14 Round Robin

Есть процессы:

P1
P2
P3

Каждый получает небольшой квант времени.

После выполнения кванта незавершённый процесс возвращается в конец очереди.

Почему Queue?

Например:

P1 P2 P3

После работы P1:

P2 P3 P1

После P2:

P3 P1 P2

Это естественная FIFO-ротация.


example

№15 почему Deque не заменяет всё

Если Deque умеет и Stack, и Queue, зачем вообще отдельно говорить про них?

Потому что важна абстракция.

Deque технически мощнее: оба конца доступны

Но если задача требует только: FIFO — Queue лучше выражает намерение.

Если только: LIFO — Stack лучше выражает намерение.

Т.е. более универсальная структура не всегда делает код понятнее.



Упражнения

Реализация динамической Queue через RingBuffer

use ring_buffer::RingBuffer;
pub mod ring_buffer{
    pub struct RingBuffer<T> {
        buffer: Vec<Option<T>>,
        head: usize,
        tail: usize,
        len: usize,
    }
    
    impl<T> RingBuffer<T> {
        pub fn new() -> Self {
            Self::with_capacity(4)
        }
        pub fn with_capacity(capacity: usize) -> Self {
            assert!(capacity > 0);
    
            let mut buffer = Vec::with_capacity(capacity);
            buffer.resize_with(capacity, || None);
    
            Self {
                buffer,
                head: 0,
                tail: 0,
                len: 0,
            }
        }
        pub fn enqueue(&mut self, value: T) {
            if self.len == self.buffer.len() {
                self.grow();
            }
    
            self.buffer[self.tail] = Some(value);
            self.tail = (self.tail + 1) % self.buffer.len();
            self.len += 1;
        }
        pub fn dequeue(&mut self) -> Option<T> {
            if self.is_empty() {
                return None;
            }
    
            let value = self.buffer[self.head].take();
            // остаток от деления на размер коллекции, дает возможность кругового обхода
            self.head = (self.head + 1) % self.buffer.len();
            self.len -= 1;
    
            value
        }
        pub fn peek(&self) -> Option<&T> {
            if self.is_empty() {
                return None;
            }
    
            self.buffer[self.head].as_ref()
        }
        pub fn len(&self) -> usize {
            self.len
        }
        pub fn capacity(&self) -> usize {
            self.buffer.len()
        }
        pub fn is_empty(&self) -> bool {
            self.len == 0
        }
        fn grow(&mut self) {
            println!("необходимо дополнительно выделить capacity");
            let old_capacity = self.buffer.len();
            let new_capacity = old_capacity * 2;
    
            let mut new_buffer = Vec::with_capacity(new_capacity);
            new_buffer.resize_with(new_capacity, || None);
    
            for i in 0..self.len {
                let old_index = (self.head + i) % old_capacity;
    
                new_buffer[i] = self.buffer[old_index].take();
            }
    
            self.buffer = new_buffer;
    
            self.head = 0;
            self.tail = self.len;
        }
    }
}
fn main() {
    let mut queue = RingBuffer::with_capacity(4);
    queue.enqueue("1");
    queue.enqueue("2");
    queue.enqueue("3");
    queue.dequeue();
    queue.enqueue("4");
    queue.dequeue();
    queue.enqueue("5");
    queue.enqueue("6");
    
    assert_eq!(queue.capacity(), 4);
    queue.enqueue("7");
    assert_eq!(queue.capacity(), 8);// произошло дополнительное выделение capacity

    while let Some(value) = queue.dequeue() {
        println!("{value}");
    }
}


Пример обработки запросов согласно их порядку поступления (на той же динамической Queue через RingBuffer)

use ring_buffer::RingBuffer;
pub mod ring_buffer{
    pub struct RingBuffer<T> {
        buffer: Vec<Option<T>>,
        head: usize,
        tail: usize,
        len: usize,
    }
    
    impl<T> RingBuffer<T> {
        pub fn new() -> Self {
            Self::with_capacity(4)
        }
        pub fn with_capacity(capacity: usize) -> Self {
            assert!(capacity > 0);
    
            let mut buffer = Vec::with_capacity(capacity);
            buffer.resize_with(capacity, || None);
    
            Self {
                buffer,
                head: 0,
                tail: 0,
                len: 0,
            }
        }
        pub fn enqueue(&mut self, value: T) {
            if self.len == self.buffer.len() {
                self.grow();
            }
    
            self.buffer[self.tail] = Some(value);
            self.tail = (self.tail + 1) % self.buffer.len();
            self.len += 1;
        }
        pub fn dequeue(&mut self) -> Option<T> {
            if self.is_empty() {
                return None;
            }
    
            let value = self.buffer[self.head].take();
            // остаток от деления на размер коллекции, дает возможность кругового обхода
            self.head = (self.head + 1) % self.buffer.len();
            self.len -= 1;
    
            value
        }
        pub fn peek(&self) -> Option<&T> {
            if self.is_empty() {
                return None;
            }
    
            self.buffer[self.head].as_ref()
        }
        pub fn len(&self) -> usize {
            self.len
        }
        pub fn capacity(&self) -> usize {
            self.buffer.len()
        }
        pub fn is_empty(&self) -> bool {
            self.len == 0
        }
        fn grow(&mut self) {
            let old_capacity = self.buffer.len();
            let new_capacity = old_capacity * 2;
    
            let mut new_buffer = Vec::with_capacity(new_capacity);
            new_buffer.resize_with(new_capacity, || None);
    
            for i in 0..self.len {
                let old_index = (self.head + i) % old_capacity;
    
                new_buffer[i] = self.buffer[old_index].take();
            }
    
            self.buffer = new_buffer;
    
            self.head = 0;
            self.tail = self.len;
        }
    }
}
fn main() {
    let mut requests = RingBuffer::new();
    // Сервер получает запросы
    println!("Requests: A->B->C->D");
    requests.enqueue("A");
    requests.enqueue("B");
    requests.enqueue("C");
    requests.enqueue("D");
    println!("Сейчас в очереди: {} запроса(ов)", requests.len());
    // Сервер обрабатывает их по FIFO
    while let Some(request) = requests.dequeue() {
        println!("Обрабатываем запрос {request}");
    }
}


Пример с графом, поиск в ширину (BFS) - обработка вершины в том порядке, в котором они были обнаружены (на той же динамической Queue через RingBuffer)


Граф:

        A
      /   \
     B     C
    / \     \
   D   E     F


Порядок обнаружения будет: 
A → B → C → D → E → F

use std::collections::{HashMap, HashSet};
use ring_buffer::RingBuffer;
pub mod ring_buffer{
    pub struct RingBuffer<T> {
        buffer: Vec<Option<T>>,
        head: usize,
        tail: usize,
        len: usize,
    }
    
    impl<T> RingBuffer<T> {
        pub fn new() -> Self {
            Self::with_capacity(4)
        }
        pub fn with_capacity(capacity: usize) -> Self {
            assert!(capacity > 0);
    
            let mut buffer = Vec::with_capacity(capacity);
            buffer.resize_with(capacity, || None);
    
            Self {
                buffer,
                head: 0,
                tail: 0,
                len: 0,
            }
        }
        pub fn enqueue(&mut self, value: T) {
            if self.len == self.buffer.len() {
                self.grow();
            }
    
            self.buffer[self.tail] = Some(value);
            self.tail = (self.tail + 1) % self.buffer.len();
            self.len += 1;
        }
        pub fn dequeue(&mut self) -> Option<T> {
            if self.is_empty() {
                return None;
            }
    
            let value = self.buffer[self.head].take();
            // остаток от деления на размер коллекции, дает возможность кругового обхода
            self.head = (self.head + 1) % self.buffer.len();
            self.len -= 1;
    
            value
        }
        pub fn peek(&self) -> Option<&T> {
            if self.is_empty() {
                return None;
            }
    
            self.buffer[self.head].as_ref()
        }
        pub fn len(&self) -> usize {
            self.len
        }
        pub fn capacity(&self) -> usize {
            self.buffer.len()
        }
        pub fn is_empty(&self) -> bool {
            self.len == 0
        }
        fn grow(&mut self) {
            let old_capacity = self.buffer.len();
            let new_capacity = old_capacity * 2;
    
            let mut new_buffer = Vec::with_capacity(new_capacity);
            new_buffer.resize_with(new_capacity, || None);
    
            for i in 0..self.len {
                let old_index = (self.head + i) % old_capacity;
    
                new_buffer[i] = self.buffer[old_index].take();
            }
    
            self.buffer = new_buffer;
    
            self.head = 0;
            self.tail = self.len;
        }
    }
}
fn build_graph() -> HashMap<&'static str, Vec<&'static str>> {
    HashMap::from([
        ("A", vec!["B", "C"]),
        ("B", vec!["D", "E"]),
        ("C", vec!["F"]),
        ("D", vec![]),
        ("E", vec![]),
        ("F", vec![]),
    ])
}
fn bfs(
    graph: &HashMap<&'static str, Vec<&'static str>>,
    start: &'static str,
) {
    let mut queue = RingBuffer::new();
    let mut visited = HashSet::new();

    queue.enqueue(start);
    visited.insert(start);

    while let Some(node) = queue.dequeue() {
        println!("Обрабатываем: {node}");

        if let Some(neighbors) = graph.get(node) {
            for &neighbor in neighbors {
                if !visited.contains(neighbor) {
                    visited.insert(neighbor);
                    queue.enqueue(neighbor);
                }
            }
        }
    }
}
fn main() {
    let graph = build_graph();
    bfs(&graph, "A");
}


Пример демонстрирующий удобство очереди для буферизации данных (на той же динамической Queue через RingBuffer)

Когда данные приходят быстрее, чем мы успеваем их обработать, тогда очередь играет роль промежуточного буфера.

Сеть присылает пакеты A->B->C->D..., а обработчик может разбирать только по одному за шаг. Новые данные складываются в конец буфера,а обработчик забирает старые с начала.

Например:

данные пришли:
  A B C

обработали:
  A

пока обрабатывали A, пришли:
  D E
use ring_buffer::RingBuffer;
pub mod ring_buffer{
    pub struct RingBuffer<T> {
        buffer: Vec<Option<T>>,
        head: usize,
        tail: usize,
        len: usize,
    }
    
    impl<T> RingBuffer<T> {
        pub fn new() -> Self {
            Self::with_capacity(4)
        }
        pub fn with_capacity(capacity: usize) -> Self {
            assert!(capacity > 0);
    
            let mut buffer = Vec::with_capacity(capacity);
            buffer.resize_with(capacity, || None);
    
            Self {
                buffer,
                head: 0,
                tail: 0,
                len: 0,
            }
        }
        pub fn enqueue(&mut self, value: T) {
            if self.len == self.buffer.len() {
                self.grow();
            }
    
            self.buffer[self.tail] = Some(value);
            self.tail = (self.tail + 1) % self.buffer.len();
            self.len += 1;
        }
        pub fn dequeue(&mut self) -> Option<T> {
            if self.is_empty() {
                return None;
            }
    
            let value = self.buffer[self.head].take();
            // остаток от деления на размер коллекции, дает возможность кругового обхода
            self.head = (self.head + 1) % self.buffer.len();
            self.len -= 1;
    
            value
        }
        pub fn peek(&self) -> Option<&T> {
            if self.is_empty() {
                return None;
            }
    
            self.buffer[self.head].as_ref()
        }
        pub fn len(&self) -> usize {
            self.len
        }
        pub fn capacity(&self) -> usize {
            self.buffer.len()
        }
        pub fn is_empty(&self) -> bool {
            self.len == 0
        }
        fn grow(&mut self) {
            let old_capacity = self.buffer.len();
            let new_capacity = old_capacity * 2;
    
            let mut new_buffer = Vec::with_capacity(new_capacity);
            new_buffer.resize_with(new_capacity, || None);
    
            for i in 0..self.len {
                let old_index = (self.head + i) % old_capacity;
    
                new_buffer[i] = self.buffer[old_index].take();
            }
    
            self.buffer = new_buffer;
    
            self.head = 0;
            self.tail = self.len;
        }
    }
}
fn main() {
    let mut buffer = RingBuffer::with_capacity(3);

    // Источник данных прислал сразу несколько элементов
    buffer.enqueue("Packet A");
    buffer.enqueue("Packet B");
    buffer.enqueue("Packet C");

    println!("Сейсас в буфере: {}", buffer.len());

    // Обработчик успел обработать только один
    if let Some(packet) = buffer.dequeue() {
        println!("Обработан: {packet}");
    }

    // Пока обработчик работал, пришли новые данные
    buffer.enqueue("Packet D");
    buffer.enqueue("Packet E");

    println!("В буфере теперь: {}", buffer.len());

    // Теперь обработчик постепенно разбирает накопившиеся данные
    while let Some(packet) = buffer.dequeue() {
        println!("Обработан: {packet}");
    }
}


Реализация Deque и демонстрация работы в роли Queue и Stack

pub mod deque {
    pub struct Deque<T> {
        buffer: Vec<Option<T>>,
        head: usize,
        tail: usize,
        len: usize,
    }

    impl<T> Deque<T> {
        pub fn new() -> Self {
            Self::with_capacity(4)
        }
        pub fn with_capacity(capacity: usize) -> Self {
            assert!(capacity > 0);

            let mut buffer = Vec::with_capacity(capacity);
            buffer.resize_with(capacity, || None);

            Self {
                buffer,
                head: 0,
                tail: 0,
                len: 0,
            }
        }
        // добавить справа
        pub fn push_back(&mut self, value: T) {
            if self.len == self.buffer.len() {
                self.grow();
            }
            self.buffer[self.tail] = Some(value);
            self.tail = (self.tail + 1) % self.buffer.len();
            self.len += 1;
        }
        // добавить слева
        pub fn push_front(&mut self, value: T) {
            if self.len == self.buffer.len() {
                self.grow();
            }
            self.head = (self.head + self.buffer.len() - 1) % self.buffer.len();
            self.buffer[self.head] = Some(value);
            self.len += 1;
        }
        // удалить слева
        pub fn pop_front(&mut self) -> Option<T> {
            if self.is_empty() {
                return None;
            }
            let value = self.buffer[self.head].take();
            self.head = (self.head + 1) % self.buffer.len();
            self.len -= 1;
            value
        }
        // удалить справа
        pub fn pop_back(&mut self) -> Option<T> {
            if self.is_empty() {
                return None;
            }
            self.tail = (self.tail + self.buffer.len() - 1) % self.buffer.len();
            let value = self.buffer[self.tail].take();
            self.len -= 1;
            value
        }
        pub fn peek_front(&self) -> Option<&T> {
            if self.is_empty() {
                return None;
            }
            self.buffer[self.head].as_ref()
        }
        pub fn peek_back(&self) -> Option<&T> {
            if self.is_empty() {
                return None;
            }
            let index = (self.tail + self.buffer.len() - 1) % self.buffer.len();
            self.buffer[index].as_ref()
        }
        pub fn len(&self) -> usize {
            self.len
        }
        pub fn is_empty(&self) -> bool {
            self.len == 0
        }
        fn grow(&mut self) {
            let old_capacity = self.buffer.len();
            let new_capacity = old_capacity * 2;
            let mut new_buffer = Vec::with_capacity(new_capacity);
            new_buffer.resize_with(
                new_capacity,
                || None,
            );
            for i in 0..self.len {
                let old_index = (self.head + i) % old_capacity;
                new_buffer[i] = self.buffer[old_index].take();
            }
            self.buffer = new_buffer;
            self.head = 0;
            self.tail = self.len;
        }
    }
}
use deque::Deque;

fn main() {
    fn fill(queue: &mut Deque<&'static str>) {
        queue.push_back("A");
        queue.push_back("B");
        queue.push_back("C");
    }

    // Используем Deque как Queue
    println!("Deque как Queue (FIFO):");
    let mut deque = Deque::new();
    fill(&mut deque);
    while let Some(value) = deque.pop_front() {
        println!("{value}");// A->B->C
    }
    
    // Используем тот же Deque как Stack (LIFO)
    println!("\nDeque как Stack (LIFO):");
    fill(&mut deque);

    while let Some(value) = deque.pop_back() {
        println!("{value}");
    }
}


Примр с Sliding Window

Sliding Window — это приём работы с частью перекрывающейся последовательности, мы не хотим каждый раз анализировать весь массив целиком. Мы берём только кусок фиксированного размера, например окно размером k = 3

Окно сдвигается на одну позицию, чтобы рассмотреть все возможные соседние подмассивы длины k, при чем соседние окна перекрываются, чтобы рассмотреть все возможные соседние подмассивы.

Sliding Window обычно применяется в задачах где что-то вроде:

  • для каждых 3 соседних элементов
  • для последних 10 секунд
  • для последних 100 запросов
  • для каждого подмассива длины k

Задача: для каждого участка из 3 соседних элементов найти максимальный элемент.

Например для массива [1, 3, -1, -3, 5, 3, 6, 7] при k = 3 двигаем окно на 1 элемент и ищим максимум:

[1  3 -1]             max = 3
   [3 -1 -3]          max = 3
      [-1 -3 5]       max = 5
         [-3 5 3]     max = 5
            [5 3 6]   max = 6
              [3 6 7] max = 7

В результате максимумы всех окон [3, 3, 5, 5, 6, 7]

Deque здесь нужен не для того, чтобы быстро хранить кандидатов на максимум текущего окна.

pub mod deque {
    pub struct Deque<T> {
        buffer: Vec<Option<T>>,
        head: usize,
        tail: usize,
        len: usize,
    }

    impl<T> Deque<T> {
        pub fn new() -> Self {
            Self::with_capacity(4)
        }
        pub fn with_capacity(capacity: usize) -> Self {
            assert!(capacity > 0);

            let mut buffer = Vec::with_capacity(capacity);
            buffer.resize_with(capacity, || None);

            Self {
                buffer,
                head: 0,
                tail: 0,
                len: 0,
            }
        }
        // добавить справа
        pub fn push_back(&mut self, value: T) {
            if self.len == self.buffer.len() {
                self.grow();
            }
            self.buffer[self.tail] = Some(value);
            self.tail = (self.tail + 1) % self.buffer.len();
            self.len += 1;
        }
        // добавить слева
        pub fn push_front(&mut self, value: T) {
            if self.len == self.buffer.len() {
                self.grow();
            }
            self.head = (self.head + self.buffer.len() - 1) % self.buffer.len();
            self.buffer[self.head] = Some(value);
            self.len += 1;
        }
        // удалить слева
        pub fn pop_front(&mut self) -> Option<T> {
            if self.is_empty() {
                return None;
            }
            let value = self.buffer[self.head].take();
            self.head = (self.head + 1) % self.buffer.len();
            self.len -= 1;
            value
        }
        // удалить справа
        pub fn pop_back(&mut self) -> Option<T> {
            if self.is_empty() {
                return None;
            }
            self.tail = (self.tail + self.buffer.len() - 1) % self.buffer.len();
            let value = self.buffer[self.tail].take();
            self.len -= 1;
            value
        }
        pub fn peek_front(&self) -> Option<&T> {
            if self.is_empty() {
                return None;
            }
            self.buffer[self.head].as_ref()
        }
        pub fn peek_back(&self) -> Option<&T> {
            if self.is_empty() {
                return None;
            }
            let index = (self.tail + self.buffer.len() - 1) % self.buffer.len();
            self.buffer[index].as_ref()
        }
        pub fn len(&self) -> usize {
            self.len
        }
        pub fn is_empty(&self) -> bool {
            self.len == 0
        }
        fn grow(&mut self) {
            let old_capacity = self.buffer.len();
            let new_capacity = old_capacity * 2;
            let mut new_buffer = Vec::with_capacity(new_capacity);
            new_buffer.resize_with(
                new_capacity,
                || None,
            );
            for i in 0..self.len {
                let old_index = (self.head + i) % old_capacity;
                new_buffer[i] = self.buffer[old_index].take();
            }
            self.buffer = new_buffer;
            self.head = 0;
            self.tail = self.len;
        }
    }
}
use deque::Deque;

fn sliding_window_max(arr: &[i32], k: usize) -> Vec<i32> {
    let mut deque: Deque<usize> = Deque::new();
    let mut result = Vec::new();

    for i in 0..arr.len() {

        // 1. Удаляем индексы, которые уже вышли из окна
        while let Some(&front_index) = deque.peek_front() {
            if front_index + k <= i {
                deque.pop_front();
            } else {
                break;
            }
        }

        // 2. Удаляем справа элементы меньше текущего
        while let Some(&back_index) = deque.peek_back() {
            if arr[back_index] <= arr[i] {
                deque.pop_back();
            } else {
                break;
            }
        }

        // 3. Добавляем текущий индекс
        deque.push_back(i);

        // 4. Когда первое полное окно сформировано,
        // максимум всегда находится в front
        if i + 1 >= k {
            let max_index = *deque.peek_front().unwrap();
            result.push(arr[max_index]);
        }
    }

    result
}

fn main() {
    let arr = [1, 3, -1, -3, 5, 3, 6, 7];

    let result = sliding_window_max(&arr, 3);

    println!("{:?}", result);
}


Пример убывающего Monotonic Deque

В monotonic deque мы специально не храним все элементы. Мы храним только те элементы, которые ещё могут оказаться полезными для ответа.

Для убывающего Monotonic Deque перед добавлением нового элемента удаляем справа все элементы меньше нового. Для возрастающего наоборот: удаляем справа все элементы больше нового и слева всегда будет минимальный элемент.

Monotonic Deque имеет смысл только внутри алгоритма, где нужно быстро поддерживать min или max среди актуальных элементов.

Задача: Есть поток измерений нагрузки на сервер: 4, 2, 12, 3, 8, 7

Нас интересует не вся история, а только последние 3 измерения.

После каждого нового значения нужно быстро знать максимум среди последних трёх.

То есть:

  • пришли 4, 2, 12 → максимум 12
  • пришло 3, актуальны 2, 12, 3 → максимум 12
  • пришло 8, актуальны 12, 3, 8 → максимум 12
  • пришло 7, актуальны 3, 8, 7 → максимум 8

Monotonic Deque хранит не все значения, а только тех кандидатов, которые ещё могут стать максимумом в текущих последних 3 измерениях.

pub mod deque {
    pub struct Deque<T> {
        buffer: Vec<Option<T>>,
        head: usize,
        tail: usize,
        len: usize,
    }

    impl<T> Deque<T> {
        pub fn new() -> Self {
            Self::with_capacity(4)
        }
        pub fn with_capacity(capacity: usize) -> Self {
            assert!(capacity > 0);

            let mut buffer = Vec::with_capacity(capacity);
            buffer.resize_with(capacity, || None);

            Self {
                buffer,
                head: 0,
                tail: 0,
                len: 0,
            }
        }
        // добавить справа
        pub fn push_back(&mut self, value: T) {
            if self.len == self.buffer.len() {
                self.grow();
            }
            self.buffer[self.tail] = Some(value);
            self.tail = (self.tail + 1) % self.buffer.len();
            self.len += 1;
        }
        // добавить слева
        pub fn push_front(&mut self, value: T) {
            if self.len == self.buffer.len() {
                self.grow();
            }
            self.head = (self.head + self.buffer.len() - 1) % self.buffer.len();
            self.buffer[self.head] = Some(value);
            self.len += 1;
        }
        // удалить слева
        pub fn pop_front(&mut self) -> Option<T> {
            if self.is_empty() {
                return None;
            }
            let value = self.buffer[self.head].take();
            self.head = (self.head + 1) % self.buffer.len();
            self.len -= 1;
            value
        }
        // удалить справа
        pub fn pop_back(&mut self) -> Option<T> {
            if self.is_empty() {
                return None;
            }
            self.tail = (self.tail + self.buffer.len() - 1) % self.buffer.len();
            let value = self.buffer[self.tail].take();
            self.len -= 1;
            value
        }
        pub fn peek_front(&self) -> Option<&T> {
            if self.is_empty() {
                return None;
            }
            self.buffer[self.head].as_ref()
        }
        pub fn peek_back(&self) -> Option<&T> {
            if self.is_empty() {
                return None;
            }
            let index = (self.tail + self.buffer.len() - 1) % self.buffer.len();
            self.buffer[index].as_ref()
        }
        pub fn len(&self) -> usize {
            self.len
        }
        pub fn is_empty(&self) -> bool {
            self.len == 0
        }
        fn grow(&mut self) {
            let old_capacity = self.buffer.len();
            let new_capacity = old_capacity * 2;
            let mut new_buffer = Vec::with_capacity(new_capacity);
            new_buffer.resize_with(
                new_capacity,
                || None,
            );
            for i in 0..self.len {
                let old_index = (self.head + i) % old_capacity;
                new_buffer[i] = self.buffer[old_index].take();
            }
            self.buffer = new_buffer;
            self.head = 0;
            self.tail = self.len;
        }
    }
}

use deque::Deque;

#[derive(Debug)]
struct Measurement {
    index: usize,
    value: i32,
}

fn main() {
    let values = [4, 2, 12, 3, 8, 7];
    let window_size = 3;

    let mut deque: Deque<Measurement> = Deque::new();

    for (index, &value) in values.iter().enumerate() {

        // 1. Удаляем слева элементы,
        // которые уже вышли из последних 3 измерений
        while let Some(front) = deque.peek_front() {
            if front.index + window_size <= index {
                deque.pop_front();
            } else {
                break;
            }
        }

        // 2. Удаляем справа элементы меньше нового значения
        while let Some(back) = deque.peek_back() {
            if back.value <= value {
                deque.pop_back();
            } else {
                break;
            }
        }

        // 3. Добавляем новое измерение
        deque.push_back(Measurement {
            index,
            value,
        });

        // 4. Когда уже есть 3 измерения,
        // слева всегда лежит максимум
        if index + 1 >= window_size {
            let max = deque.peek_front().unwrap();

            println!(
                "Последние 3 измерения заканчиваются на {}: max = {}",
                value,
                max.value
            );
        }
    }
}


Пример, обхода в ширину (BFS) с разными приоритетами типа 0-1 BFS

Здесь Deque нужен потому, что у нас есть два типа рёбер:

  • вес 0 — переход почти “бесплатный”, его нужно обработать раньше;
  • вес 1 — переход дороже, его можно обработать позже.

Граф:
        A
      /   \
   0 /     \ 1
    B       C
 0 / \ 1     \ 0
  D   E       F

Веса рёбер:
A → B  вес 0
A → C  вес 1
B → D  вес 0
B → E  вес 1
C → F  вес 0

Обычный BFS сохраняет порядок обнаружения: A → B → C → D → E → F, а 0-1 BFS двигает вершины с более дешёвым переходом вперёд.

C 0-1 BFS мы используем Deque так:

  • вес 0 → push_front
  • вес 1 → push_back

В итоге путь с учетом приоритета: A → B → D → C → F → E

pub mod deque {
    pub struct Deque<T> {
        buffer: Vec<Option<T>>,
        head: usize,
        tail: usize,
        len: usize,
    }

    impl<T> Deque<T> {
        pub fn new() -> Self {
            Self::with_capacity(4)
        }
        pub fn with_capacity(capacity: usize) -> Self {
            assert!(capacity > 0);

            let mut buffer = Vec::with_capacity(capacity);
            buffer.resize_with(capacity, || None);

            Self {
                buffer,
                head: 0,
                tail: 0,
                len: 0,
            }
        }
        // добавить справа
        pub fn push_back(&mut self, value: T) {
            if self.len == self.buffer.len() {
                self.grow();
            }
            self.buffer[self.tail] = Some(value);
            self.tail = (self.tail + 1) % self.buffer.len();
            self.len += 1;
        }
        // добавить слева
        pub fn push_front(&mut self, value: T) {
            if self.len == self.buffer.len() {
                self.grow();
            }
            self.head = (self.head + self.buffer.len() - 1) % self.buffer.len();
            self.buffer[self.head] = Some(value);
            self.len += 1;
        }
        // удалить слева
        pub fn pop_front(&mut self) -> Option<T> {
            if self.is_empty() {
                return None;
            }
            let value = self.buffer[self.head].take();
            self.head = (self.head + 1) % self.buffer.len();
            self.len -= 1;
            value
        }
        // удалить справа
        pub fn pop_back(&mut self) -> Option<T> {
            if self.is_empty() {
                return None;
            }
            self.tail = (self.tail + self.buffer.len() - 1) % self.buffer.len();
            let value = self.buffer[self.tail].take();
            self.len -= 1;
            value
        }
        pub fn peek_front(&self) -> Option<&T> {
            if self.is_empty() {
                return None;
            }
            self.buffer[self.head].as_ref()
        }
        pub fn peek_back(&self) -> Option<&T> {
            if self.is_empty() {
                return None;
            }
            let index = (self.tail + self.buffer.len() - 1) % self.buffer.len();
            self.buffer[index].as_ref()
        }
        pub fn len(&self) -> usize {
            self.len
        }
        pub fn is_empty(&self) -> bool {
            self.len == 0
        }
        fn grow(&mut self) {
            let old_capacity = self.buffer.len();
            let new_capacity = old_capacity * 2;
            let mut new_buffer = Vec::with_capacity(new_capacity);
            new_buffer.resize_with(
                new_capacity,
                || None,
            );
            for i in 0..self.len {
                let old_index = (self.head + i) % old_capacity;
                new_buffer[i] = self.buffer[old_index].take();
            }
            self.buffer = new_buffer;
            self.head = 0;
            self.tail = self.len;
        }
    }
}
use deque::Deque;
use std::collections::HashMap;

fn build_graph() -> HashMap<&'static str, Vec<(&'static str, u32)>> {
    HashMap::from([
        ("A", vec![("B", 0), ("C", 1)]),
        ("B", vec![("D", 0), ("E", 1)]),
        ("C", vec![("F", 0)]),
        ("D", vec![]),
        ("E", vec![]),
        ("F", vec![]),
    ])
}

fn zero_one_bfs(
    graph: &HashMap<&'static str, Vec<(&'static str, u32)>>,
    start: &'static str,
) {
    let mut deque = Deque::new();

    let mut distance: HashMap<&str, u32> = HashMap::new();

    for &node in graph.keys() {
        distance.insert(node, u32::MAX);
    }

    distance.insert(start, 0);

    deque.push_front(start);

    while let Some(node) = deque.pop_front() {
        let current_distance = distance[node];

        println!("Обрабатываем {node}, distance = {current_distance}");

        for &(neighbor, weight) in &graph[node] {
            let new_distance = current_distance + weight;

            if new_distance < distance[neighbor] {
                distance.insert(neighbor, new_distance);

                if weight == 0 {
                    deque.push_front(neighbor);
                } else {
                    deque.push_back(neighbor);
                }
            }
        }
    }

    println!("\nМинимальная стоимость от A:");

    for node in ["A", "B", "C", "D", "E", "F"] {
        println!("{node}: {}", distance[node]);
    }
}

fn main() {
    let graph = build_graph();

    zero_one_bfs(&graph, "A");
}

Hash Table

Визуализация работы Hash Table

Hash Table — структура данных для хранения пар: key → value, где key одного типа.

Например:

"user_42" → User
"email@example.com" → Account

12345 → User
1292 → Account

Ключ преобразуется в число с помощью hash function, а уже число используется как индекс bucket'а. Внутри bucket может быть список, динамический массив, дерево и т.д., зависит от выбранного способа разрешения коллизий.

Hash Table ознакомление

Hash Table (Separate Chaining) это массив, где каждая ячейка содержит коллекцию элементов:

bucket 0 → [ ]
bucket 1 → [ (key,value) → (key,value) ]
bucket 2 → [ ]
bucket 3 → [ (key,value) ]

Классическая Hash Table почти всегда как основное хранилище использует обычный массив, каждая ячейка которого называется bucket, потому что именно быстрый доступ к bucket по индексу даёт ожидаемое .

Например, наша примитивная реализация Hash Table основана на масиве из 8 ячеек.

Желаем получить доступ к: key = "apple"

Сначала вычисляем hash: hash("apple") = 928374

Затем получаем индекс массива (bucket = число от 0 до bucket_count - 1): 928374 % 8 = 6

bucket — это место в таблице, куда hash определил хранить элемент

Значит элемент попадает в bucket 6 и мы просто берем значение по индексу из массива hash_table[6] за

Проблема collision (коллизия) возникает когда мы получаем общий bucket для разных ключей:

hash("apple") % 8 = 6
hash("orange") % 8 = 6

Поэтому bucket на практике может содержать несколько элементов:

  • separate chaining способ разрешения коллизий который хранит в одном bucket коллекцию совпавших хешей hash_table[6]=[("apple", 100),("orange", 200),... ] При поиске по этому bucket'у, для решения коллизии, приходится дополнительно сравнивать ключи в этой коллекции. Ухудшает cache locality и требуют дополнительной памяти для организации хранения коллекций.
  • open addressing способ разрешения коллизий, где несколько элементов не лежат внутри одного bucket-списка, а занимают разные ячейки самого массива Hash Table. Также хранит в ячейке пару hash_table[6]=[(key, value)] но в случае совпадения ключа с занятой ячейкой просто ищет следующее место рядом по одному из вариантов probing. Например вариант linear probing просто возьмет соседнюю свободную ячейку, а при поиске будет сравнивать все ключи после полученного hash т.е. hash определяет только начальную позицию поиска, а все эдементы где-то рядом или нет, например мы искали key но встретили пустую ячейку.

Hash-функция — это функция, которая принимает произвольные данные key и преобразует их в некоторое числовое значение фиксированного размера, которое Hash Table использует как индекс для bucket. Hash-функция определяет только bucket, а внутри bucket уже нужно проверить соответствие искомому key если попалась коллизия.

При большом количестве коллизий поиск внутри bucket может становиться медленнее, поэтому Hash Table следит за тем, чтобы таблица не была слишком заполнена, и периодически увеличивает количество bucket'ов (resize/rehash), что является дорогой операцией так как количество bucket'ов учитывается в определении номера bucket'а в самой Hash Table.

Качество hash-функции очень важно! Качество hash-функции — одна из важных составляющих производительности Hash Table. Hash-функция фактически определяет, насколько равномерно элементы распределяются по bucket'ам. Если hash-функция неравномерно распределяет bucket'ы то данные кучкуются в bucket'ах и поиск становится линейным . При этом hash-функция не обязана гарантировать уникальный результат, разные ключи могут получить одинаковый hash.

Hash-функция не обязана сама выдавать число от 0 до bucket_count - 1, этим может занятся Hash Table преобразовав hash в индекс.

Hash-функция должна прежде всего хорошо перемешивать ключи, чтобы похожие ключи не постоянно попадали в одинаковые или близкие bucket'ы, и желательно маленькое изменение ключа должно сильно менять hash, это помогает избежать закономерностей в распределении. И наконец, hash-функция должна быть достаточно быстрой. Нет смысла получать идеальное распределение, если вычисление hash для каждого поиска само по себе очень дорогое. Быстрый хешер может быть отличным для внутренних данных приложения, но хуже подходить для данных, которые контролирует пользователь или атакующий.

Сводка по hash-функции для поддержания быстрой работы Hash Table:

  1. Быстро вычисляться
  2. Давать равномерное распределение
  3. Сильно перемешивать данные
  4. Давать одинаковый hash для одинакового входа

Как избежать коллизий

Вариант perfect hashing — хеш-функция без коллизий для конкретного набора ключей. Т.е. мы этот набор ключей знаем и проверили его на отсутвие коллизий.

Вариант где ключ уже является уникальным числовым индексом, но тогда Hash Table не нужна, используем массив.

Для динамической Hash Table, где ключи постоянно добавляются и удаляются, построить одну универсальную функцию без коллизий для любых возможных ключей нельзя, если пространство ключей значительно больше количества доступных slot'ов.

если пространство возможных ключей больше пространства hash-значений, коллизии математически неизбежны

За возможно иметь ожидаемый поиск мы платим повышенным расходом памяти. Память расходуется на сам массив bucket'ов, свободные ячейки для поддержания низкой загрузки таблицы и хранение ключей вместе со значениями. В обычной Hash Table мы не можем просто отказаться от хранения ключей, поскольку возможны коллизии: одинаковый bucket может соответствовать нескольким разным ключам. Поэтому после вычисления hash необходимо дополнительно проверить сам ключ, чтобы убедиться, что найденное значение действительно соответствует искомому ключу.

Hash Table — это скорее базовая концепция/способ организации данных, а HashMap и HashSet — конкретные абстракции, которые обычно реализуются на основе Hash Table. Hash Table — это способ реализации структуры хранения через хеширование: массив bucket'ов + hash function + обработка коллизий.

Hash Table описывает прежде всего механизм/структуру организации хранения, а HashMap — абстракцию ассоциативного массива key → value

Структуры реализованные на основе Hash Table:

  • HashMap хранит пары key → value
  • HashSet хранит только уникальные элементы key

Сильные стороны Hash Table

  • Поиск по ключу в среднем O(1)
  • Вставка по ключу в среднем O(1)
  • Удаление по ключу в среднем O(1)
  • Хорошо подходит для произвольных ключей (если можно получить hash и сравнить), а не только целочисленных индексов
  • Размер структуры может динамически изменяться
  • Удобно реализует отображение: key → value
  • Хорошо подходит для проверки существования элемента
  • На основе Hash Table удобно реализовывать Map и Set

Слабые стороны Hash Table

  • Нет естественного порядка элементов
  • Память расходуется не только на сами элементы. Таблица обычно держит свободные bucket'ы и свободную capacity, чтобы поддерживать низкий load factor и уменьшать количество коллизий
  • Hash Table имеет плохую cache locality по сравнению с непрерывными структурами вроде массива, поэтому последовательная итерация по всем элементам может быть относительно дорогой. Нужно просматривать сами bucket'ы, включая пустые. Особенно это заметно при разрозненном размещении элементов в памяти, например при separate chaining.
  • Не подходит для задач, где нужны диапазоны
  • В худшем случае операции могут деградировать до O(n), из-за большого количества коллизий
  • Resize / rehash может быть дорогим, так как индекс зависит от размера таблицы, поэтому нельзя просто увеличить массив и оставить элементы на старых местах. Нужно пройти по всем существующим элементам и определить для каждого новый bucket. Поэтому средняя стоимость вставки остаётся
  • Возможны hash collisions
  • Не позволяет эффективно найти: минимум/максимум, следующий/предыдущий... без дополнительной организации данных

Сложность операций Hash Table

ОперацияСреднееХудшее
insert
get by key
remove by key
contains key
полный обход

Среднее O(1) достигается при хорошем распределении hash-функции и нормальном количестве свободных buckets.

Память

Hash Table обычно хранит не только сами элементы, но еще их ключи и свободные ячейки между ними.

Поэтому Memory Overhead выше, чем у компактного массива.

Часть buckets может быть пустой. Это сделано намеренно, чтобы уменьшить количество collisions. Сободные bucket'ы нужны именно как запас пространства для распределения новых элементов по их идеальным местам. Если идеальное место ключа уже занято, тогда ему нужно найти новое место, что замедляет как вставку так и поиск.

Когда использовать Hash Table

  • Нужно часто искать объект по уникальному ключу
  • Нужно быстро проверять наличие значения
  • Ключи не являются последовательными индексами
  • Нужно хранить соответствие:
id → object
email → user
word → count
  • Порядок элементов не важен
  • Нужна дедупликация значений через Set
  • Нужно считать частоты элементов (сколько раз каждый элемент встречается)

Когда не использовать Hash Table

  • Нужен отсортированный порядок
  • Нужны диапазоны
  • Нужно часто получать минимальный или максимальный ключ
  • Нужно обходить элементы строго в порядке добавления
  • Ключи и так являются плотными индексами: 0, 1, 2, 3, 4... в таком случае массив может быть проще и компактнее.

Задачи

Свойства Hash Table:

  • key → value — основная модель
  • hash function — преобразует ключ в hash
  • bucket — место хранения
  • collision — разные ключи могут попасть в одно место
  • average O(1) — основные операции обычно константные
  • worst-case O(n) — при плохом распределении возможна деградация
  • load factor — насколько таблица заполнена
  • rehashing — перераспределение элементов после расширения
  • unordered — структура обычно не поддерживает сортировку ключей
  • HashMap — key/value
  • HashSet — только уникальные значения

example

№1 поиск пользователя по ID

Есть 50 миллионов пользователей.

У каждого: id, name, email

Основная операция: получить пользователя по id

ID выглядят так:

918273
51
872364923
...
Подходит ли Hash Table?

Да. Можно хранить: id → User

Поиск по id в среднем:

В массиве пришлось бы либо искать , либо использовать огромный разреженный массив.


example

№2 поиск по индексу

Есть ровно 1000 объектов.

Объекты всегда обращаются так:

object[0]
object[1]
object[2]
...
Нужна ли Hash Table?

Скорее нет. Ключи уже являются плотными индексами.

Массив: array[index] даёт и имеет меньший Memory Overhead.

Hash Table здесь добавит hash calculation и buckets без явной пользы.


example

№3 проверка существования

Программа получает миллионы email.

Нужно быстро отвечать: был ли мы этот email раньше?

Что использовать?

Использовать HashSet, при поступлении проверять наличие его: contains(email)

Если ключа нет в коллекции, тогда добавить: insert(email)

Проверка и вставка в среднем за


example

№4 подсчёт слов

Есть текст: cat dog cat bird dog cat

Нужно узнать количество каждого слова.

Подходит ли Hash Map?

Да. Храним: word → count

После обработки:

cat  → 3
dog  → 2
bird → 1

Для каждого слова: map[word] += 1


example

№5 range query

Есть миллион записей: timestamp → event

Нужно очень часто находить: все события между 10:00 и 11:00

Подходит ли Hash Table?

Для точного поиска: timestamp = 10:34:52 может подходить.

Но для диапазона: 10:00 .. 11:00 нет, Hash Table не хранит ключи в отсортированном порядке.

Придётся либо пройти всю таблицу, либо использовать дополнительную структуру.

Для range queries обычно лучше дерево или отсортированная структура.


example

№6 collision

Hash Table имеет capacity = 8

Два ключа после вычисления позиции, получаем одинаковый индекс bucket'а:

key A → bucket 3
key B → bucket 3
Это ошибка?

Нет, это обычная hash collision.

Hash Table должна уметь хранить оба значения.


example

№7 удаление по ключу

Есть: session_id → Session

Пользователь завершает сессию.

Нужно быстро удалить: session_id = "abc123"

Подходит ли Hash Table?

Да, по ключу можно найти соответствующий элемент и удалить его в среднем за


example

№8 сортировка пользователей

Есть: id → User

Но нужно постоянно получать id пользователей: от самого минимального до самого максимального

Достаточно ли Hash Table?

Нет, Hash Table не поддерживает ключи в отсортированном порядке.

Для такого требования нужна другая структура или дополнительная сортировка.


example

№9 два способа поиска

Есть миллион пользователей.

Нужно:

часто обходить всех пользователей
часто искать пользователя по id
Нужно ли выбирать только Array или Hash Table?

Нет, удобней распределить роли по структурам (secondary index).

Можно использовать:

Array<User>
HashMap<UserId, indexArray>

Array удобен для компактного хранения и быстрого последовательного обхода.

HashMap обеспечивает быстрый поиск: id → index


example

№10 resize

Hash Table почти заполнена.

Добавляется ещё много элементов.

Почему одна вставка иногда может быть дорогой?

Если таблица становится слишком заполненной, то есть растёт load factor (Separate Chaining): load factor = количество элементов / количество bucket'ов

При превышении порога, например load factor = 0.75, происходит rehashing это увеличение количество buckets в таблице с пересчетом их индекса bucket'а с применением снова hash-функции.

Но нельзя просто скопировать старые элементы в те же индексы. Потому что bucket определяется через размер таблицы: index = hash(key) % capacity

Поэтому при rehashing нужно пройти по всем элементам и заново определить их bucket для нового размера таблицы, именно поэтому операция называется re-hashing

Поэтому отдельное расширение может быть O(n), хотя обычная вставка в среднем O(1).


example

№11 уникальные значения

Есть: 5, 7, 5, 3, 7, 9, 3

Нужно получить уникальные значения.

Что использовать?

HashSet:

5
7
3
9

Повторная вставка уже существующего значения ничего нового не добавляет.


example

№12 порядок добавления

В Hash Table добавили: A -> B -> C -> D

Нужно гарантированно получить при обходе: A -> B -> C -> D

Можно ли рассчитывать на это?

Для обычной Hash Table — нет.

Положение элементов определяется hash и buckets, а не порядком добавления.

Если порядок важен, нужно использовать структуру, которая явно его гарантирует.



Упражнения

Пример выбора Hasher

use std::collections::HashMap;
use std::hash::BuildHasherDefault;
use std::collections::hash_map::DefaultHasher;

// Hasher DefaultHasher стандартный BuildHasher для HashMap. 
// Он создаёт хешеры, использующие случайно выбранное состояние/seed.
// Один и тот же ключ не обязан получить одинаковый hash между разными экземплярами HashMap.
// Это сделано прежде всего для защиты от hash-flooding атак, когда злоумышленник 
//  специально подбирает много ключей, вызывающих коллизии.
type MyMap<K, V> = HashMap<K, V, BuildHasherDefault<DefaultHasher>>;

fn main() {
    let mut map: MyMap<String, i32> = MyMap::default();

    map.insert("apple".to_string(), 100);
    map.insert("banana".to_string(), 200);

    println!("{}", map["apple"]);
}

Пример подсчета слов

use std::collections::HashMap;
   
fn main() {
    let text = "cat dog cat bird dog cat";

    let mut word_count = HashMap::new();

    for word in text.split_whitespace() {
        *word_count.entry(word).or_insert(0) += 1;
    }

    for (word, count) in &word_count {
        println!("{word} → {count}");
    }
}

Пример плохой hash-функции

Например, можно специально сделать максимально плохой хешер: всегда возвращать одно и то же значение. Тогда абсолютно все ключи попадут в один bucket и возникнут постоянные коллизии.

Но Hash Table все равно будет работать корректно, просто неэффективно, по сути мы используем линеный поиск внутри одного bucket'а, вместо доступа по индексу к bucket'ам


use std::collections::HashMap;
use std::hash::{BuildHasher, Hasher};

#[derive(Default)]
struct BadHasher {
    hash: u64,
}
impl Hasher for BadHasher {
    fn finish(&self) -> u64 {
        self.hash
    }
    fn write(&mut self, _bytes: &[u8]) {
        self.hash = 0;
    }
}

#[derive(Clone, Default)]
struct BadBuildHasher;

impl BuildHasher for BadBuildHasher {
    type Hasher = BadHasher;

    fn build_hasher(&self) -> Self::Hasher {
        BadHasher::default()
    }
}
fn main() {
    let text = "cat dog cat bird dog cat";
    
    let mut word_count: HashMap<&str, i32, BadBuildHasher> =
        HashMap::with_hasher(BadBuildHasher);

    for word in text.split_whitespace() {
        *word_count.entry(word).or_insert(0) += 1;
    }
    for (word, count) in &word_count {
        println!("{word} → {count}");
    }
}

Binary Search Tree (BST)

Визуализация работы Binary Search Tree

Визуализация работы Binary Search Tree

Главное назначение деревьев: представлять и эффективно обрабатывать иерархические данные или организовывать данные так, чтобы поиск/вставка/удаление были эффективнее линейного перебора.

Дерево организует элементы иерархически — один элемент может иметь несколько дочерних элементов.

В линейной структуре такой как массив, организация элементов идет последовательно, элементы следуют друг за другом: [10, 20, 30, 40, 50, 60, 70], что дает хорошую cache locality для быстрой итерации и если массив отсортирован, то бинарный поиск в нем тоже быстрый как и у Binary Search Tree, но вот поддержание состояние сортированности в массиве дороже. При поступлении новых данных, массив вынужден будет сдвигать все элементы справа со сложностью , а в самобалансирующемся бинарном дереве поиска после вставки или удаления может потребоваться балансировка с помощью поворотов. благодаря этому поиск, вставка и удаление сохраняют в худшем случае.

BST ознакомление

Binary Search Tree — бинарное дерево, в котором для каждого узла выполняется правило:

все значения слева < node
все значения справа > node

Пример:

        8
      /   \
     3     10
    / \      \
   1   6      14
      / \    /
     4   7  13

Для узла 8:

слева  → 1, 3, 4, 6, 7   < 8
справа → 10, 13, 14      > 8

Специализированные виды BST со своим видом алгоритма балансировки:

  • AVL Tree — BST + строгий контроль разницы высот
  • Red-Black Tree — BST + цвет каждого узла + набор правил
  • Treap — BST по ключу + heap по приоритету
  • Splay Tree — BST, где узлы поднимаются поворотами после обращений

Сильные стороны

  • Поиск может выполняться за O(log n), если дерево сбалансировано
  • Вставка может выполняться за O(log n)
  • Удаление может выполняться за O(log n)
  • Ключи хранятся в упорядоченном виде
  • Хорошо подходит для range query:
    • минимальный элемент
    • максимальный элемент
    • следующий элемент
    • предыдущий элемент
  • Inorder traversal возвращает значения в отсортированном порядке
  • В отличие от Hash Table сохраняет отношение порядка между ключами

Слабые стороны

  • Производительность зависит от формы дерева. Главная проблема обычного BST — оно может потерять баланс и превратиться в Linked List. Производительность BST зависит от высоты дерева: сбалансированное дерево даёт , а сильно перекошенное может деградировать до . Именно поэтому существуют самобалансирующиеся деревья — AVL, Red-Black Tree и т. д. Они не позволяют дереву сильно вытягиваться.
  • Требуется дополнительная память на ссылки left и right. И узлы разбросаны по памяти, поэтому cache locality хуже массива
  • Для точного поиска по ключу Hash Table в среднем быстрее: O(1) против O(log n)

Сложность операций

Для сбалансированного BST:

ОперацияСреднееХудшее
Поиск
Вставка
Удаление
Min
Max
Полный обход
Range query

k — количество элементов, попавших в диапазон.

Память

Типичный узел:

[value | left | right]

Например:

struct Node<T> {
    value: T,
    left: Option<Box<Node<T>>>,
    right: Option<Box<Node<T>>>,
}

Каждый узел хранит:

  • значение
  • ссылку на левое поддерево
  • ссылку на правое поддерево

Memory Overhead выше массива.

Когда использовать

  • Нужно часто искать по ключу
  • Нужен отсортированный порядок
  • Недостаточно только точного поиска как у Hash Table
    • нужны range queries,
    • нужно часто получать min/max
  • Нужно находить следующий/предыдущий элемент
  • Данные постоянно вставляются и удаляются

Когда не использовать

  • Нужен только точный поиск по ключу, а порядок не важен → Hash Table обычно лучше
  • Нужен доступ по индексу → Array
  • Нужен минимальный Memory Overhead → Array
  • Дерево никак не балансируется, а данные могут приходить уже отсортированными
  • Нужен гарантированный быстрый поиск, но используется обычный несбалансированный BST

Основные понятия

root

Корневой узел.

          root
        /      \
leaf child     leaf child
leaf

Узел без детей.

left subtree

Поддерево, где все значения меньше текущего узла.

      5
     / \
    3   6
   / \
  1   4 
right subtree

Поддерево, где все значения больше текущего узла.

    10
      \
      14
      / \
    11  15  
height

Максимальная длина пути от узла до самого глубокого leaf.

Высота дерева напрямую влияет на скорость поиска.

balanced tree

Сбалансированное дерево, у которого высота остаётся примерно

Например:

        8
      /   \
     4     12
    / \    / \
   2   6  10 14
degenerate tree

Вырожденное дерево:

1
 \
  2
   \
    3
     \
      4

По сути становится Linked List.

Высота:

search path

Путь, который проходит поиск.

Например ищем 10:

        8
      /   \
     4     12
    / \    / \
   2   6  10 14
8 → 12 → 10

На каждом шаге отбрасывается одно из поддеревьев.

successor

Следующий по значению элемент.

Например для 6: successor = 7

predecessor

Предыдущий по значению элемент.

Для 6: predecessor = 4

range query

Запрос вида: найти все значения от 5 до 12

BST может не обходить заведомо неподходящие поддеревья.

DFS — Depth-First Search / Traversal

Обход в глубину: выбираем ветку и идём по ней максимально глубоко, потом возвращаемся назад.

У дерева есть три основных DFS-обхода. Разница только в том, когда мы обрабатываем текущий узел относительно его детей.

Для BST очень часто используют inorder, потому что он использует главное свойство BST и даёт отсортированный порядок.

1. Pre-order traversal — прямой обход (NLR)

Дерево обходится по схеме: node → left → right

Сначала обрабатываем родителя, потом его поддеревья. Полезен, когда нужно сначала обработать объект, а потом его содержимое: например копирование дерева, сериализация структуры.

Для:

        8
      /   \
     3     10
    / \
   1   6

получаем: 8 3 1 6 10

2. In-order traversal — симметричный обход (LNR)

Дерево обходится по схеме: Левое поддерево → Корень → Правое поддерево, что дает элементы в порядке возрастания.

Обход: left → node → right

Для BST он возвращает значения в отсортированном порядке.

Для:

        8
      /   \
     3     10
    / \
   1   6

получаем: 1 3 6 8 10

3. Post-order traversal — обратный обход (LRN)

Сначала левое поддерево, затем правое, и только потом текущий узел.

Обход: left → right → node

Для:

        8
      /   \
     3     10
    / \
   1   6

получаем: 1 6 3 10 8

4. Reverse in-order traversal — обратный симметричный обход (RNL)

Обход бинарного дерева поиска (BST) в порядке убывания.

Дерево обходится по схеме: Правое поддерево → Корень → Левое поддерево, что дает элементы в порядке убывания.

Обход: right → node → left

Для:

        8
      /   \
     3     10
    / \
   1   6

получаем: 10 8 6 3 1

BFS — Breadth-First Search / Level-Order Traversal

Обход в ширину: обходим уровень за уровнем. Вывод не сортированный.

Здесь естественно используется Queue (FIFO).

BFS / level-order чаще нужен, когда важны уровни дерева: поиск ближайшего узла, вычисление ширины, просмотр структуры по уровням, минимальная глубина и подобные задачи.

Для:

        8
      /   \
     3     10
    / \
   1   6

получаем: 8 3 10 1 6

Логика обхода: Начинаем с корня и сразу его выводим 8, а его детей добавляем в очередь начиная с левого узла enqueue(3), enqueue(10). Следующий шаг достаем из очереди первый элемент и выводим 3, а его детей добавляем в очередь enqueue(1), enqueue(6). Достаем из очереди следующий элемент и выводим 10, детей у него нет, поэтому достаем из очереди следующий элемент и выводим 1, детей у него нет, поэтому достаем из очереди следующий элемент и выводим 6

Удаление элементов дерева

Нельзя просто выбросить узел, нужно сохранить порядок элементов BST.

Общий принцип:

  1. найти successor
  2. заменить значение удаляемого узла
  3. удалить successor из его старой позиции
1. Удаление leaf
    8
   / \
  3   10

Удаляем leaf 3

У него нет детей, поэтому ссылка родителя просто становится пустой:

    8
     \
      10
2. Удаление узла с одним ребёнком
8
 \
  10
    \
     14

Удаляем узел 10

У 10 один ребёнок — 14

Родитель 8 теперь будет ссылаться напрямую на 14:

8
 \
  14
3. Удаление узла с двумя детьми

Есть два стандартных равноценных варианта при удалении узла с двумя детьми:

  1. inorder successor заменить на successor → найти минимальный элемент справа (т.е. самое маленькое из всех больших значений)
  2. inorder predecessor заменить на predecessor → найти максимальный элемент слева (т.е. самое маленькое из всех больших значений)

№1 inorder successor

        8
      /   \
     3     10
          /  \
         9   14

Удаляем узел 10

Обычно используют inorder successor т.е. минимальный элемент правого поддерева от удаляемого узла. Правое поддерево от узла 10 состоит только из leaf 14. Поэтому inorder successor(10)=14 получаем дерево с сохраненным порядком:

        8
      /   \
     3     14
          /  
         9   

№2 inorder successor

        8
      /   \
     3     10
          /  \
         9    14
                \
                 18

Удаляем узел 10, минимальный элемент правого поддерева от удаляемого узла по прежнему узел 14. Поэтому inorder successor(10)=14

        8
      /   \
     3     14
          /  \
         9    18

№3 inorder successor

        8
      /   \
     3     10
          /  \
         9    14
             / \
           13   18
          /
         11

Удаляем узел 10, минимальный элемент правого поддерева от удаляемого узла, это leaf 11. Поэтому inorder successor(10)=11

        8
      /   \
     3     11
          /  \
         9    14
             / \
           13   18          

№4 inorder successor

        8
      /   \
     3     10
          /  \
         9    14
              /
            12
              \
               13

Удаляем узел 10, минимальный элемент правого поддерева от удаляемого узла, это узел 12 и его ребенок займет его место. Поэтому inorder successor(10)=12

        8
      /   \
     3     12
          /  \
         9    14
              /
            13
             

№1 inorder predecessor

        8
      /   \
     3     10
          /  \
         9   14

Удаляем узел 10, цель - найти максимальный элемент слева от удаляемого узла, это leaf 9. Поэтому inorder predecessor(10)=9

        8
      /   \
     3     9
            \
             14

№2 inorder predecessor

        5
      /   \
     3     10
          /  \
         8    14
          \     \
           9     18

Удаляем узел 10, цель - найти максимальный элемент слева от удаляемого узла, это leaf 9. Поэтому inorder predecessor(10)=9

        5
      /   \
     3     9
          /  \
         8    14
                \
                 18

№3 inorder predecessor

        5
      /   \
     3     10
          /  \
         8    14
        / \     
       7   9 
             

Удаляем узел 10, цель - найти максимальный элемент слева от удаляемого узла, это leaf 9. Поэтому inorder predecessor(10)=9

        5
      /   \
     3     9
          /  \
         8    14
        /       
       7    
             

Имеет смысл использовать AVL / Red-Black Tree, потому что главная проблема обычного BST — оно может потерять баланс и превратиться в Linked List.


Задачи

example

№1 поиск

Есть BST:

        8
      /   \
     3     10
    / \      \
   1   6      14
      / \    /
     4   7  13

Нужно найти 7

Как проходит поиск?

Сравниваем с 8.

7 < 8

идём влево.

Сравниваем с 3.

7 > 3

идём вправо.

Сравниваем с 6.

7 > 6

идём вправо.

Находим 7.

Путь:

8 → 3 → 6 → 7

Не нужно обходить остальные узлы.


example

№2 почему поиск быстрый

Есть сбалансированный BST из примерно миллиона элементов.

Почему поиск близок к O(log n)?

На каждом сравнении одно из поддеревьев полностью исключается из поиска.

Если дерево хорошо сбалансировано, количество оставшихся кандидатов примерно уменьшается вдвое.

Поэтому высота около: log₂(n)

Для миллиона элементов это порядка 20 уровней.


example

№3 плохая форма дерева

Вставляем в обычный BST именно в таком порядке: 1, 2, 3, 4, 5

Что получится?
1
 \
  2
   \
    3
     \
      4
       \
        5

Дерево вырождается.

Поиск значения 5, сложность становится :

1 → 2 → 3 → 4 → 5

Для исправления ситуации необходимо самобалансировка, но это уже будет специализированный вид BST со своим видом алгоритма балансировки.


example

№4 минимальный элемент

Как найти минимальный элемент в BST?

Как найти максимальный элемент в BST?

В какую сторону двигаться

Для поиска минимального элемента, нужно идти всё время влево:

root
 ↓ left
 ↓ left
 ↓ left

Пока left == None.

Самый левый узел — минимум.

Для максимального элемента, нужно идти всё время вправо.


example

№5 отсортированный вывод

    8
   / \
  3   10
     /  \
    9    14
        /
       12
Как вывести все значения BST по возрастанию

Использовать inorder traversal:

left → node → right

Из-за свойства BST результат будет отсортирован.

  1. Проверить все левое поддерево каждого родительского узла
  2. Вывести родителя
  3. Проверить все правое поддерево каждого родительского узла

При проверки поддеревьев так же сперва проверяем левое поддерево, потом родителя, потом правое поддерево.

  • Начинаем обход с корня 8, не печатая его.
  • Вывод 3, так как мы начали с левого поддерева и это leaf
  • Вывод 8, родителя
  • Вывод 9, так как у правого поддерева с родителем 10 есть leaf слева
  • Вывод 10, родителя
  • Вывод 12, так как у правого поддерева с родителем 14 есть leaf 12
  • Вывод 14, родителя

Вывод: 3, 8, 9, 10, 12, 14


Как вывести все значения BST по убыванияю

Использовать reverse in-order traversal:

right → node → left

Из-за свойства BST результат будет отсортирован.

  1. Проверить все правое поддерево каждого родительского узла
  2. Вывести родителя
  3. Проверить все левое поддерево каждого родительского узла

При проверки поддеревьев так же сперва проверяем правое поддерево, потом родителя, потом левое поддерево.

  • Начинаем обход с корня 8, не печатая его.
  • Вывод 14, так как мы дошли до самого глубокого правого поддерева и у родителя 14 нет справа leaf
  • Вывод 12, так как у правого поддерева с родителем 14 есть leaf слева
  • ...

Вывод: 14, 12, 10, 9, 8, 3


example

№6 range query

Есть BST с миллионом чисел.

Нужно найти все значения: от 1000 до 2000

Почему BST удобен?

Если текущий узел меньше 1000, левое поддерево можно не обходить.

Если текущий узел больше 2000, правое поддерево можно не обходить.

То есть дерево позволяет отсекать целые ветви.

В сбалансированном дереве: O(log n + k)

где k — количество найденных элементов


example

№7 Hash Table или BST

Основная операция:

получить User по точному id

Range query и сортировка не нужны.

Что лучше Hash Table или BST?

Hash Table обычно лучше.

Hash Table → average O(1)
BST        → O(log n)

BST имеет смысл, если нужен порядок ключей.


example

№8 нужен следующий элемент

Хранятся временные метки событий.

Нужно часто находить: первое событие после timestamp X

Почему BST полезен?

Потому что ключи упорядочены.

Можно искать не только точное значение, но и ближайшее большее:

successor

Hash Table такой порядок не хранит.


example

№9 удаление leaf

Есть:

    8
   / \
  3   10

Удаляем 3

Что происходит?

3 — leaf

У него нет детей, поэтому ссылка родителя просто становится пустой:

    8
     \
      10

example

№10 удаление узла с одним ребёнком

Есть:

8
 \
  10
    \
     14

Удаляем 10

Что происходит?

У 10 один ребёнок — 14

Родитель 8 начинает ссылаться напрямую на 14:

8
 \
  14

example

№11 удаление узла с двумя детьми

Есть:

        8
      /   \
     3     10
          /  \
         9   14

Удаляем 10

Что происходит?

Обычно используют inorder successor т.е. минимальный элемент правого поддерева от удаляемого узла. Правое поддерево от узла 10 состоит только из leaf 14

        8
      /   \
     3     14
          /  
         9   


Упражнения

Реализация структур данных со сложными связями между узлами — например деревьев, двусвязных списков и графов — в Rust затруднительна из-за строгой модели ownership и borrowing.

В таких структурах часто нужно, чтобы узлы ссылались друг на друга в нескольких направлениях, чтобы один узел был доступен из разных мест, а связи между узлами можно было изменять во время работы алгоритма.

В Rust при этом нужно явно соблюдать правила владения и заимствований: кто владеет узлом, сколько ссылок на него существует, какие из них mutable и остаются ли они валидными после изменения структуры.

Поэтому реализации, которые в C или C++ естественно строятся на обычных указателях, в Rust требуют более сложных подходов: Rc<RefCell<T>>, Weak, arena с индексами либо raw pointers / NonNull и unsafe.

Именно сочетание сложных связей между узлами с правилами ownership и borrowing делает реализацию таких структур в Rust заметно сложнее.

Вот даже книга есть Learn Rust With Entirely Too Many Linked Listsi

Стандартных нормальный способ для реализации дерева с поддержкой обратных ссылок это использование Weak:

  • Rc от родителя к ребёнку означает: родитель владеет ребёнком.
  • Weak от ребёнка к родителю означает: ребёнок знает родителя, но не владеет им.
#![allow(unused)]
fn main() {
struct Node {
    value: i32,
    parent: Option<Weak<RefCell<Node>>>,// поэтому strong reference cycle не возникает
    left: Option<Rc<RefCell<Node>>>,
    right: Option<Rc<RefCell<Node>>>,
}
}

Но код становится тяжелее и borrow-проверки частично уходят из compile time в runtime через RefCell

Суть в том, что RefCell<T> позволяет делать mutable borrow даже тогда, когда снаружи у нас только shared ссылка на сам RefCell. Но проверка правил заимствования происходит уже не компилятором, а во время выполнения в runtime.

#![allow(unused)]
fn main() {
  // При использовании обычных ссылок &T и &mut T правила заимствования проверяются компилятором на этапе compile time
  // Компилятор сразу запрещает две одновременные mutable-ссылки
  let mut x = 10;
  let a = &mut x;
  let b = &mut x; // compile error

  // RefCell<T> реализует interior mutability и переносит проверку правил заимствования для borrow() / borrow_mut() в runtime
  let x = RefCell::new(10);
  let a = x.borrow_mut();
  let b = x.borrow_mut(); // compile проходит, но в runtime panic
}

Еще один хороший способ, использовать в качестве узла Option<Box<Node>> — это хорошая базовая реализация. Она проста, безопасна и хорошо отражает ownership дерева.

Box не допускает циклического ownership, потому что каждый объект имеет одного владельца и ownership нельзя замкнуть обратно (reference cycles) без нарушения самой модели владения. Но мы ограничены просмотром только сверху вниз, мы не можем узнать родителя имеея его ребенка. И обычный граф неудобно моделировать только через Box, потому что вершина графа может иметь несколько входящих ссылок, а Box предполагает единственного владельца. Это становится неудобно для некоторых алгоритмов:

  • найти successor, двигаясь вверх
  • перестройка связей, балансировка AVL / Red-Black Tree
  • удаление, где удобно быстро обратиться к parent
  • перемещение узлов по дереву

Но Option<Box<Node>> удобно использовать для простоты изучения алгоритмов работы с деревом.

Книга Learn Rust With Entirely Too Many Linked Lists не даёт универсального ответа, вариант зависит от требований структуры. Обычное дерево с владением сверху вниз Box<Node> / Option<Box<Node>>, это самый простой и безопасный вариант. Но если нужна низкоуровневая структура с двусторонними ссылками, rotations, стабильными адресами и полным контролем → raw pointers / NonNull, но уже через unsafe. При этом книга очень явно подчёркивает, насколько raw pointers опасны и сколько инвариантов приходится гарантировать самому.

Реализация BST через Option<Box<Node>>

use bst::BinarySearchTree;
mod bst{
    use std::collections::VecDeque;
    
    #[derive(Debug)]
    struct Node {
        value: i32,
        left: Option<Box<Node>>,
        right: Option<Box<Node>>,
    }
    
    impl Node {
        fn new(value: i32) -> Self {
            Self {
                value,
                left: None,
                right: None,
            }
        }
        fn insert(&mut self, value: i32) {
            if value < self.value {
                match self.left {
                    Some(ref mut left) => left.insert(value),
                    None => {
                        self.left = Some(Box::new(Node::new(value)));
                    }
                }
            } else if value > self.value {
                match self.right {
                    Some(ref mut right) => right.insert(value),
                    None => {
                        self.right = Some(Box::new(Node::new(value)));
                    }
                }
            }
        }
        fn preorder(&self) {
            print!("{} ", self.value);
            if let Some(ref left) = self.left {
                left.preorder();
            }
            if let Some(ref right) = self.right {
                right.preorder();
            }
        } 
        fn inorder(&self) {
            if let Some(ref left) = self.left {
                left.inorder();
            }
            print!("{} ", self.value);
            if let Some(ref right) = self.right {
                right.inorder();
            }
        }
        fn reverse_inorder(&self) {
            if let Some(ref right) = self.right {
                right.reverse_inorder();
            }
            print!("{} ", self.value);
            if let Some(ref left) = self.left {
                left.reverse_inorder();
            }
        }
        fn range(&self, min: i32, max: i32, result: &mut Vec<i32>) {
            if self.value > min {
                if let Some(ref left) = self.left {
                    left.range(min, max, result);
                }
            }
            if self.value >= min && self.value <= max {
                result.push(self.value);
            }
            if self.value < max {
                if let Some(ref right) = self.right {
                    right.range(min, max, result);
                }
            }
        }
        fn contains(&self, value: i32) -> bool {
            if value == self.value {
                return true;
            }
            if value < self.value {
                match &self.left {
                    Some(left) => left.contains(value),
                    None => false,
                }
            } else {
                match &self.right {
                    Some(right) => right.contains(value),
                    None => false,
                }
            }
        }
        fn find(&self, value: i32) -> Option<i32> {
            if value == self.value {
                return Some(self.value);
            }
            if value < self.value {
                match &self.left {
                    Some(left) => left.find(value),
                    None => None,
                }
            } else {
                match &self.right {
                    Some(right) => right.find(value),
                    None => None,
                }
            }
        }
        fn remove(node: Option<Box<Node>>, value: i32) -> Option<Box<Node>> {
            let mut node = node?;
            if value < node.value {
                node.left = Node::remove(node.left, value);
                return Some(node);
            }
            if value > node.value {
                node.right = Node::remove(node.right, value);
                return Some(node);
            }
            // Нашли удаляемый узел
            match (node.left, node.right) {
                // Нет детей
                (None, None) => None,
    
                // Только правый ребёнок
                (None, Some(right)) => Some(right),
    
                // Только левый ребёнок
                (Some(left), None) => Some(left),
    
                // Два ребёнка
                (Some(left), Some(right)) => {
                    let successor = Node::min_value(&right);
                    node.value = successor;
                    node.left = Some(left);
                    node.right = Node::remove(Some(right), successor);
    
                    Some(node)
                }
            }
        }
        fn min_value(node: &Node) -> i32 {
            match &node.left {
                Some(left) => Node::min_value(left),
                None => node.value,
            }
        }
        fn min(&self) -> i32 {
            match &self.left {
                Some(left) => left.min(),
                None => self.value,
            }
        }
        fn max(&self) -> i32 {
            match &self.right {
                Some(right) => right.max(),
                None => self.value,
            }
        }
        fn len(&self) -> usize {
            let left_len = match &self.left {
                Some(left) => left.len(),
                None => 0,
            };
            let right_len = match &self.right {
                Some(right) => right.len(),
                None => 0,
            };
            1 + left_len + right_len
        }
        fn height(&self) -> usize {
            let left_height = match &self.left {
                Some(left) => left.height(),
                None => 0,
            };
            let right_height = match &self.right {
                Some(right) => right.height(),
                None => 0,
            };
            1 + left_height.max(right_height)
        }
    }
    
    pub struct BinarySearchTree {
        root: Option<Box<Node>>,
    }
    
    impl BinarySearchTree {
        pub fn new() -> Self {
            Self { root: None }
        }
        pub fn clear(&mut self) {
            // Rust автоматически уничтожает все поддеревья
            self.root = None;
        }
        pub fn is_empty(&self) -> bool {
            self.root.is_none()
        }
        pub fn insert(&mut self, value: i32) {
            match self.root {
                Some(ref mut root) => root.insert(value),
                None => {
                    self.root = Some(Box::new(Node::new(value)));
                }
            }
        }
        pub fn preorder(&self) {
            if let Some(ref root) = self.root {
                root.preorder();
            }
            println!();
        }
        pub fn inorder(&self) {
            if let Some(ref root) = self.root {
                root.inorder();
            }
            println!();
        }
        pub fn reverse_inorder(&self) {
            if let Some(ref root) = self.root {
                root.reverse_inorder();
            }
            println!();
        }
        pub fn level_order(&self) {
            let mut queue: VecDeque<&Node> = VecDeque::new();
            if let Some(root) = self.root.as_deref() {
                queue.push_back(root);
            }
            while let Some(node) = queue.pop_front() {
                print!("{} ", node.value);
                if let Some(left) = node.left.as_deref() {
                    queue.push_back(left);
                }
                if let Some(right) = node.right.as_deref() {
                    queue.push_back(right);
                }
            }
            println!();
        }
        pub fn range(&self, min: i32, max: i32) -> Vec<i32> {
            let mut result = Vec::new();
            if let Some(ref root) = self.root {
                root.range(min, max, &mut result);
            }
            result
        }
        pub fn successor(&self, value: i32) -> Option<i32> {
            let mut current = self.root.as_ref();
            let mut successor = None;
            while let Some(node) = current {
                if value < node.value {
                    successor = Some(node.value);
                    current = node.left.as_ref();
                } else {
                    current = node.right.as_ref();
                }
            }
            successor
        }
        pub fn predecessor(&self, value: i32) -> Option<i32> {
            let mut current = self.root.as_ref();
            let mut predecessor = None;
            while let Some(node) = current {
                if value > node.value {
                    predecessor = Some(node.value);
                    current = node.right.as_ref();
                } else {
                    current = node.left.as_ref();
                }
            }
            predecessor
        }
        pub fn contains(&self, value: i32) -> bool {
            match &self.root {
                Some(root) => root.contains(value),
                None => false,
            }
        }
        pub fn find(&self, value: i32) -> Option<i32> {
            match &self.root {
                Some(root) => root.find(value),
                None => None,
            }
        }
        pub fn remove(&mut self, value: i32) {
            self.root = Node::remove(self.root.take(), value);
        }
        pub fn min(&self) -> Option<i32> {
            self.root.as_ref().map(|root| root.min())
        }
        pub fn max(&self) -> Option<i32> {
            self.root.as_ref().map(|root| root.max())
        }
        pub fn len(&self) -> usize {
            match &self.root {
                Some(root) => root.len(),
                None => 0,
            }
        }
        pub fn height(&self) -> usize {
            match &self.root {
                Some(root) => root.height(),
                None => 0,
            }
        }
        // Поиск первого элемента >= x
        pub fn lower_bound(&self, value: i32) -> Option<i32> {
            let mut current = self.root.as_ref();
            let mut result = None;
    
            while let Some(node) = current {
                if node.value >= value {
                    result = Some(node.value);
                    current = node.left.as_ref();
                } else {
                    current = node.right.as_ref();
                }
            }
            result
        }
        // Поиск первого элемента > x
        pub fn upper_bound(&self, value: i32) -> Option<i32> {
            let mut current = self.root.as_ref();
            let mut result = None;
    
            while let Some(node) = current {
                if node.value > value {
                    result = Some(node.value);
                    current = node.left.as_ref();
                } else {
                    current = node.right.as_ref();
                }
            }
            result
        }
    } 
}
fn main() {
    let mut tree = BinarySearchTree::new();
/*
Создадим дерево:

         8
      /    \
     3     10
    / \      \
   1   6     14
      / \    /
     4   7  13
*/ 
    for value in [8, 3, 10, 1, 6, 14, 4, 7, 13] {
        tree.insert(value);
    }
    
    println!("Количество узлов в дереве: {}", tree.len());
    // Высоту дерева полезно знать как раз чтобы видеть, насколько дерево выродилось
    println!("Высота дерева: {}", tree.height());
    println!("\nПоиск min/max:");
    println!("min = {:?}", tree.min());
    println!("max = {:?}", tree.max());

    println!("\nDFS — Depth-First Search / Traversal:");
    println!("Preorder traversal (прямой обход)");
    tree.preorder();
    println!("\nInorder traversal (симметричный обход)");
    tree.inorder();
    println!("\nReverse inorder traversal (обратный симметричный обход)");
    tree.reverse_inorder();
    
    println!("\nBFS — Breadth-First Search / Level-Order Traversal:");
    println!("Level order:");
    tree.level_order();
    
    // Range query
    // Не нужно обходить всё дерево. 
    // Если текущий узел меньше нижней границы то всё левое поддерево
    //  можно пропустить, потому что там значения ещё меньше. 
    // Если текущий узел больше верхней границы,
    //  то всё правое поддерево 14 можно пропустить.
    println!("\nRange query (найти все значения от 4 до 13):");
    let values = tree.range(4, 13);
    println!("{:?}", values);
     
    println!("\nПроверка наличия узла 7: {}", tree.contains(7));  // true
    println!("Проверка наличия узла 12: {}", tree.contains(12)); // false
    
    println!("\nПоиск узла:");
    match tree.find(6) {
        Some(value) => println!("Найдено значение: {}", value),
        None => println!("Значение не найдено"),
    }

    println!("\nСледующий элемент — successor(5) = {:?}:", tree.successor(5));
    println!("Предыдущий элемент — predecessor(5) = {:?}:", tree.predecessor(5));
    
    println!("\nУдаление корня");
    tree.remove(8);
    println!("оставшиеся узлы дерева (симметричный обход):");
    tree.inorder();
    
    println!("\nПоиск lower_bound/upper_bound:");
    println!("{:?}", tree.lower_bound(5));  // Some(6)
    println!("{:?}", tree.lower_bound(6));  // Some(6)
    println!("{:?}", tree.lower_bound(11)); // Some(13)
    println!("{:?}", tree.lower_bound(15)); // None
    
    println!("{:?}", tree.upper_bound(5));  // Some(6)
    println!("{:?}", tree.upper_bound(6));  // Some(7)
    println!("{:?}", tree.upper_bound(10)); // Some(13)
    println!("{:?}", tree.upper_bound(14)); // None

    println!("\nУдаление дерева:");
    tree.clear();
    println!("Количество узлов в дереве: {}", tree.len());      // 0
    println!("Проверка на пустоту дерева: {}", tree.is_empty()); // true
    
    // Пример вырожденного дерева (degenerate tree)
    println!("\nПример вырожденного дерева (degenerate tree):");
    let mut tree = BinarySearchTree::new();
/*
Создадим дерево:

1
 \
  2
   \
    3
     \
      4
       \
        5
        
Формально это всё ещё BST, но по сути оно стало похоже на linked list:    
height = n
search = O(n)
insert = O(n)
remove = O(n)

Чтобы этого избежать, добавляют алгоритм самобалансировки.
*/ 
    let n = 5;
    for value in 0..n {
        tree.insert(value);
    }
    println!("Высота дерева: {}", tree.height());// Высота: O(n) 
}

Self-balancing Binary Search Tree (Self-balancing BST)

Red-Black Tree — наиболее универсальный вариант. Обеспечивает гарантированную логарифмическую высоту и хорошо подходит для частых вставок, удалений и поисков. Именно поэтому этот тип дерева используется во многих стандартных библиотечных структурах данных. Каждый узел имеет дополнительный цвет RED или BLACK, но цвета сами по себе ничего не означают для поиска. Они используются как набор правил, позволяющих контролировать высоту дерева.

AVL — сильный кандидат для поиска. Строго контролирует баланс высот поддеревьев. Обычно дерево получается более компактным по высоте, чем Red-Black Tree, поэтому AVL часто выбирают для структур с большим количеством поисковых запросов и сравнительно редкими вставками и удалениями. При большом количестве вставок/удалений Red-Black Tree часто практичнее.

Обычное бинарное дерево поиска (BST) хорошо работает только пока оно остаётся достаточно сбалансированным т.е. никогда. Мы не контролируем порядок поступления ключей, а дерево может выродиться в список, превратив поиск, вставку и удаление из в . AVL и Red-Black решают именно эту проблему: после изменений они автоматически поддерживают дерево достаточно сбалансированным.

info

Упорядоченность и эффективные операции с диапазонами — одни из главных преимуществ Tree

(повторение - мать учения)

Red-Black Tree

В сравнении с другими структурами данных:

HashMap / HashSet
→ быстрый поиск
→ порядка нет

Heap
→ быстрый min/max
→ произвольный поиск слабый

Vec + sort
→ хорош для почти неизменяемых данных

Red-Black Tree
→ поиск + порядок + диапазоны + min/max + insert/remove

Визуализация работы Red-Black Tree

Red-Black Tree ознакомление

Сильные стороны

  • Эффективено при смешанном workload: Search, Insert, Remove гарантированно работают за
  • Не может деградировать в линейную структуру
  • Обычно требуется меньше структурных изменений при вставках и удалениях, чем в AVL

Слабые стороны

  • Непредсказуемая стоимость отдельной операции. Хотя поиск, вставка и удаление имеют гарантированную сложность , количество поворотов и перекрашиваний зависит от формы дерева и конкретной операции. Это усложняет оценку константных затрат и оптимизацию под конкретную нагрузку
  • Дополнительная память. Помимо ключей и значений, каждый узел хранит ссылки на другие узлы и цвет

Сложность операций

ОперацияRed-Black
SearchO(log n)
InsertO(log n)
RemoveO(log n)
Min / MaxO(log n)
Successor / PredecessorO(log n)
TraversalO(n)

Память

Каждый узел должен хранить цвет — обычно один бит логической информации. Фактические расходы зависят от выравнивания и компоновки структуры в памяти: отдельное поле не обязательно увеличит размер узла ровно на один байт, но может повлиять на padding.

Когда использовать

  • нужны отсортированные данные;
  • часто выполняются и поиск, и вставки, и удаления;
  • нужны lower_bound, upper_bound, range;
  • нужны min, max, successor, predecessor;
  • структура постоянно изменяется.

Когда не использовать

  • если нужны быстрые операции с неупорядоченными ключами, часто лучше подходит Hash Table
  • данные редко изменяются и можно один раз отсортировать массив

Основные понятия

Вместе эти свойства ограничивают высоту дерева:

  1. Каждый узел либо RED, либо BLACK

  2. Root — BLACK

  3. RED node не может иметь RED ребенка или RED родителя. Это запрещает два красных узла подряд, поэтому между чёрными узлами может находиться максимум один красный.

  4. Все пути от узла до листьев содержат одинаковое количество BLACK nodes

  5. Новые узлы обычно вставляются RED что бы не менять высоту черных узлов. Black-Height Property решающим является не общее количество чёрных узлов в дереве, а одинаковое количество чёрных узлов на всех путях от любого узла до его NIL-листьев.

important

Но в первую очередь, необходимо разобраться с применением Tree, а не с его деталями реализации.


Упражнения

1. Упорядоченное множество (ordered set)

RedBlackTree удобно использовать как упорядоченное множество (ordered set) — множество уникальных значений, которое автоматически поддерживает их в отсортированном порядке.

В отличие от HashSet, здесь можно не только быстро проверить наличие элемента, но и получить минимальное, максимальное и пройти все значения по порядку.

RedBlackTree хороший выбор, когда нужны одновременно: уникальность, быстрый поиск, динамические вставки/удаления и сохранение порядка.

Типичные применения:

  • ID пользователей
  • timestamp событий
  • набор цен
  • приоритеты
  • отсортированные ключи

Хранение уникальные значения ID пользователей в отсортированном виде:

fn main() {
    let mut user_ids = RedBlackTree::new();

    // Добавляем ID пользователей.
    user_ids.insert(1042);
    user_ids.insert(501);
    user_ids.insert(2500);
    user_ids.insert(1200);

    // Повторная вставка того же значения не создаёт дубликат.
    user_ids.insert(501);

    println!("Все ID по порядку:");

    for id in user_ids.iter() {
        println!("{id}");
    }

    println!();
    println!("Минимальный ID: {:?}", user_ids.first());
    println!("Максимальный ID: {:?}", user_ids.last());

    println!();
    println!("Есть ли пользователь 1200: {}", user_ids.contains(&1200));
    println!("Есть ли пользователь 999: {}", user_ids.contains(&999));

    // Удаляем пользователя.
    user_ids.remove(&1042);

    println!();
    println!("После удаления 1042:");

    for id in user_ids.iter() {
        println!("{id}");
    }
}














/// -------------------------------------------
/// Implementation RBT
/// -------------------------------------------


pub use tree::RedBlackTree;
pub use iter::{IterInOrder, Range};
pub use iter::IterPreOrder;
pub use iter::IterReverseInOrder;
pub use iter::IterPostOrder;
 
pub mod iter{
    use std::ptr::NonNull;

    use crate::node::{Link, Node};

    ///```text
    ///
    ///            4
    ///          /   \
    ///         2     9
    ///        / \   //\
    ///       1   3  7   10
    ///             / \
    ///            6   8
    ///```
    ///    Depth-First Search / Pre-order (NLR):     4, 2, 1, 3, 9, 7, 6, 8, 10
    ///    Depth-First Search / In-order (LNR):      1, 2, 3, 4, 6, 7, 8, 9, 10
    ///    Depth-First Search / Post-order (LRN):    1, 3, 2, 6, 8, 7, 10, 9, 4
    ///    Breadth-First Search / Level-order:       4, 2, 9, 1, 3, 7, 10, 6, 8 
    pub use dfs_in_order::{IterInOrder, Range};

    pub(crate) use dfs_in_order::{leftmost_child_in_order, successor_of_node_in_order};

    mod dfs_in_order {
        use super::{Link, Node, NonNull};
        use std::iter::FusedIterator;
        use std::marker::PhantomData;

        /// Returns the next node in an in-order (`LNR`) traversal.
        ///
        /// # Safety
        ///
        /// `node` must point to a live node that belongs to the current tree, and
        /// all parent/child links reachable from it must be valid.
        pub unsafe fn successor_of_node_in_order<T>(node: NonNull<Node<T>>) -> Link<T> {
            unsafe {
                if node.as_ref().right.is_some() {
                    // If a right subtree exists, the successor is its leftmost node.
                    leftmost_child_in_order(node.as_ref().right)
                } else {
                    // Otherwise, walk up through parent links until the current
                    // node is found in a left subtree.
                    parent_with_left(node)
                }
            }
        }

        /// Returns the leftmost node reachable from `node`.
        ///
        /// Returns `None` when `node` is `None`.
        ///
        /// # Safety
        ///
        /// Every pointer reachable through `left` links must refer to a live node.
        pub unsafe fn leftmost_child_in_order<T>(node: Link<T>) -> Link<T> {
            unsafe {
                if let Some(node) = node {
                    if node.as_ref().left.is_none() {
                        Some(node)
                    } else {
                        leftmost_child_in_order(node.as_ref().left)
                    }
                } else {
                    node
                }
            }
        }

        /// Walks up the parent chain until an ancestor is reached from its left child.
        ///
        /// # Safety
        ///
        /// `node` and all parent links traversed by this function must be valid.
        unsafe fn parent_with_left<T>(node: NonNull<Node<T>>) -> Link<T> {
            unsafe {
                let parent = node.as_ref().parent;
                if let Some(parent) = parent
                    && let Some(left) = parent.as_ref().left
                {
                    if std::ptr::eq(left.as_ptr(), node.as_ptr()) {
                        return Some(parent);
                    }
                    return parent_with_left(parent);
                }
                // No parent means that the root has been reached.
                None
            }
        }

        /// Iterator over a tree in in-order (`Left -> Node -> Right`, or `LNR`).
        ///
        /// For a binary search tree, this traversal yields values in ascending order.
        pub struct IterInOrder<'a, T> {
            current_node: Link<T>,
            count: usize,
            elem: Option<&'a T>,
            _boo: PhantomData<&'a T>,
        }

        impl<'a, T> IterInOrder<'a, T> {
            /// Creates an in-order iterator starting at `node`.
            pub(crate) fn new(node: Link<T>, count: usize) -> Self {
                Self {
                    current_node: node,
                    count,
                    elem: None,
                    _boo: PhantomData,
                }
            }
        }

        impl<'a, T> Iterator for IterInOrder<'a, T> {
            type Item = &'a T;

            fn next(&mut self) -> Option<Self::Item> {
                if self.count > 0 {
                    self.count -= 1;
                    if let Some(node) = self.current_node {
                        unsafe {
                            self.elem = Some(&node.as_ref().value);
                            self.current_node = successor_of_node_in_order(node);
                        }
                    } else {
                        self.elem = None;
                    }
                } else {
                    self.elem = None;
                }
                self.elem
            }

            fn size_hint(&self) -> (usize, Option<usize>) {
                (self.count, Some(self.count))
            }
        }

        impl<'a, T> ExactSizeIterator for IterInOrder<'a, T> {
            fn len(&self) -> usize {
                self.count
            }
        }

        impl<'a, T> FusedIterator for IterInOrder<'a, T> {}

        /// A lazy iterator over an inclusive range of values in a [`crate::RedBlackTree`].
        ///
        /// `Range` is created by [`crate::RedBlackTree::range`]. It yields references to
        /// values in ascending order, starting from the first value greater than or
        /// equal to the lower bound and stopping after the upper bound.
        ///
        /// The iterator does not allocate an intermediate collection. Values are
        /// produced one at a time as the iterator advances.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([1, 3, 5, 7, 9, 11]);
        ///
        /// let values: Vec<_> = tree
        ///     .range(&3, &9)
        ///     .copied()
        ///     .collect();
        ///
        /// assert_eq!(values, vec![3, 5, 7, 9]);
        /// ```
        ///
        /// The iterator can be combined with standard iterator adapters:
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend(1..=100);
        ///
        /// let values: Vec<_> = tree
        ///     .range(&20, &80)
        ///     .take(3)
        ///     .copied()
        ///     .collect();
        ///
        /// assert_eq!(values, vec![20, 21, 22]);
        /// ```
        pub struct Range<'a, T> {
            current_node: Link<T>,
            end_node: Link<T>,
            _marker: PhantomData<&'a T>,
        }

        impl<'a, T: Ord> Range<'a, T> {
            pub(crate) fn new(root: Link<T>, min: &T, max: &T) -> Self {
                if min > max {
                    return Self {
                        current_node: None,
                        end_node: None,
                        _marker: PhantomData,
                    };
                }

                unsafe {
                    let mut current = root;
                    let mut start: Link<T> = None;

                    // First node >= min.
                    while let Some(node) = current {
                        match node.as_ref().value.cmp(min) {
                            std::cmp::Ordering::Less => {
                                current = node.as_ref().right;
                            }

                            std::cmp::Ordering::Equal => {
                                start = Some(node);
                                break;
                            }

                            std::cmp::Ordering::Greater => {
                                start = Some(node);
                                current = node.as_ref().left;
                            }
                        }
                    }

                    current = root;

                    let mut end: Link<T> = None;

                    // First node > max.
                    while let Some(node) = current {
                        match node.as_ref().value.cmp(max) {
                            std::cmp::Ordering::Less | std::cmp::Ordering::Equal => {
                                current = node.as_ref().right;
                            }

                            std::cmp::Ordering::Greater => {
                                end = Some(node);
                                current = node.as_ref().left;
                            }
                        }
                    }

                    Self {
                        current_node: start,
                        end_node: end,
                        _marker: PhantomData,
                    }
                }
            }
        }

        impl<'a, T> Iterator for Range<'a, T> {
            type Item = &'a T;

            fn next(&mut self) -> Option<Self::Item> {
                let node = self.current_node?;

                if self.end_node == Some(node) {
                    self.current_node = None;
                    return None;
                }

                unsafe {
                    let value = &node.as_ref().value;

                    self.current_node = successor_of_node_in_order(node);

                    Some(value)
                }
            }
        }
    }

    pub use dfs_reverse_in_order::IterReverseInOrder;

    pub(crate) use dfs_reverse_in_order::{
        rightmost_child_reverse_in_order, successor_of_node_reverse_in_order,
    };

    mod dfs_reverse_in_order {
        use super::{Link, Node, NonNull};
        use std::marker::PhantomData;

        /// Returns the next node in reverse in-order (`Right -> Node -> Left`, or `RNL`).
        ///
        /// # Safety
        ///
        /// `node` must point to a live node that belongs to the current tree, and
        /// all parent/child links reachable from it must be valid.
        pub unsafe fn successor_of_node_reverse_in_order<T>(node: NonNull<Node<T>>) -> Link<T> {
            unsafe {
                if node.as_ref().left.is_some() {
                    // After the current node, descend into the left subtree and
                    // choose its rightmost node.
                    rightmost_child_reverse_in_order(node.as_ref().left)
                } else {
                    // Without a left subtree, walk upward until reaching an
                    // ancestor from its right subtree.
                    parent_with_right(node)
                }
            }
        }

        /// Returns the rightmost node reachable from `node`.
        ///
        /// Returns `None` when `node` is `None`.
        ///
        /// # Safety
        ///
        /// Every pointer reachable through `right` links must refer to a live node.
        pub unsafe fn rightmost_child_reverse_in_order<T>(node: Link<T>) -> Link<T> {
            unsafe {
                if let Some(node) = node {
                    if node.as_ref().right.is_none() {
                        Some(node)
                    } else {
                        rightmost_child_reverse_in_order(node.as_ref().right)
                    }
                } else {
                    None
                }
            }
        }

        /// Walks up the parent chain until an ancestor is reached from its right child.
        ///
        /// # Safety
        ///
        /// `node` and all parent links traversed by this function must be valid.
        unsafe fn parent_with_right<T>(node: NonNull<Node<T>>) -> Link<T> {
            unsafe {
                let parent = node.as_ref().parent;

                if let Some(parent) = parent
                    && let Some(right) = parent.as_ref().right
                {
                    if std::ptr::eq(right.as_ptr(), node.as_ptr()) {
                        return Some(parent);
                    }

                    return parent_with_right(parent);
                }

                None
            }
        }

        /// Iterator over a tree in reverse in-order (`Right -> Node -> Left`, or `RNL`).
        ///
        /// For a binary search tree, this traversal yields values in descending order.
        pub struct IterReverseInOrder<'a, T> {
            current_node: Link<T>,
            count: usize,
            elem: Option<&'a T>,
            _boo: PhantomData<&'a T>,
        }

        impl<'a, T> IterReverseInOrder<'a, T> {
            /// Creates a reverse in-order iterator starting at `node`.
            pub(crate) fn new(node: Link<T>, count: usize) -> Self {
                Self {
                    current_node: node,
                    count,
                    elem: None,
                    _boo: PhantomData,
                }
            }
        }

        impl<'a, T> Iterator for IterReverseInOrder<'a, T> {
            type Item = &'a T;

            fn next(&mut self) -> Option<Self::Item> {
                if self.count > 0 {
                    self.count -= 1;

                    if let Some(node) = self.current_node {
                        unsafe {
                            self.elem = Some(&node.as_ref().value);
                            self.current_node = successor_of_node_reverse_in_order(node);
                        }
                    } else {
                        self.elem = None;
                    }
                } else {
                    self.elem = None;
                }

                self.elem
            }

            fn size_hint(&self) -> (usize, Option<usize>) {
                (self.count, Some(self.count))
            }
        }
    }

    pub use dfs_pre_order::IterPreOrder;

    pub(crate) use dfs_pre_order::successor_of_node_pre_order;

    mod dfs_pre_order {
        use super::{Link, Node, NonNull};
        use std::marker::PhantomData;

        /// Returns the next node in a pre-order (`Node -> Left -> Right`, or `NLR`) traversal.
        ///
        /// # Safety
        ///
        /// `node` must point to a live node in the current tree and all traversed
        /// links must be valid.
        pub unsafe fn successor_of_node_pre_order<T>(node: NonNull<Node<T>>) -> Link<T> {
            unsafe {
                if let Some(node) = node.as_ref().left {
                    Some(node)
                } else if let Some(node) = node.as_ref().right {
                    Some(node)
                } else {
                    right_with_parent(node)
                }
            }
        }

        /// Finds the next right subtree by walking through parent links.
        ///
        /// # Safety
        ///
        /// `node` and all parent links traversed by this function must be valid.
        unsafe fn right_with_parent<T>(node: NonNull<Node<T>>) -> Link<T> {
            unsafe {
                if let Some(parent) = node.as_ref().parent {
                    next_right(Some(parent), node)
                } else {
                    None
                }
            }
        }

        /// Searches ancestors for the next unvisited right child.
        ///
        /// # Safety
        ///
        /// `child`, `node`, and all links traversed by this function must be valid.
        unsafe fn next_right<T>(node: Link<T>, child: NonNull<Node<T>>) -> Link<T> {
            unsafe {
                if let Some(n) = node {
                    if let Some(right) = n.as_ref().right {
                        if std::ptr::eq(right.as_ptr(), child.as_ptr()) {
                            next_right(n.as_ref().parent, n)
                        } else {
                            Some(right)
                        }
                    } else {
                        next_right(n.as_ref().parent, n)
                    }
                } else {
                    None
                }
            }
        }

        /// Iterator over a tree in pre-order (`Node -> Left -> Right`, or `NLR`).
        ///
        /// Pre-order traversal visits a node before either of its subtrees.
        pub struct IterPreOrder<'a, T> {
            current_node: Link<T>,
            count: usize,
            elem: Option<&'a T>,
            _boo: PhantomData<&'a T>,
        }

        impl<'a, T> IterPreOrder<'a, T> {
            /// Creates a pre-order iterator starting at `root`.
            pub(crate) fn new(root: Link<T>, count: usize) -> Self {
                Self {
                    current_node: root,
                    count,
                    elem: None,
                    _boo: PhantomData,
                }
            }
        }

        impl<'a, T> Iterator for IterPreOrder<'a, T> {
            type Item = &'a T;

            fn next(&mut self) -> Option<Self::Item> {
                if self.count > 0 {
                    self.count -= 1;
                    if let Some(node) = self.current_node {
                        unsafe {
                            self.elem = Some(&node.as_ref().value);
                            self.current_node = successor_of_node_pre_order(node);
                        }
                    } else {
                        self.elem = None;
                    }
                } else {
                    self.elem = None;
                }
                self.elem
            }

            fn size_hint(&self) -> (usize, Option<usize>) {
                (self.count, Some(self.count))
            }
        }
    }

    pub use dfs_post_order::IterPostOrder;

    pub(crate) use dfs_post_order::{leaf_post_order, successor_of_node_post_order};

    mod dfs_post_order {
        use super::{Link, Node, NonNull};
        use std::marker::PhantomData;

        /// Returns the next node in a post-order (`Left -> Right -> Node`, or `LRN`) traversal.
        ///
        /// # Safety
        ///
        /// `current_node` must point to a live node in the current tree and all
        /// traversed parent/child links must be valid.
        pub unsafe fn successor_of_node_post_order<T>(current_node: NonNull<Node<T>>) -> Link<T> {
            unsafe {
                if let Some(parent) = current_node.as_ref().parent {
                    if let Some(right) = parent.as_ref().right {
                        if std::ptr::eq(current_node.as_ptr(), right.as_ptr()) {
                            Some(parent)
                        } else {
                            Some(leaf_post_order(right))
                        }
                    } else {
                        Some(parent)
                    }
                } else {
                    None
                }
            }
        }

        /// Returns the first leaf visited by a post-order traversal starting at `node`.
        ///
        /// # Safety
        ///
        /// `node` must point to a live node and all descendant links traversed by
        /// this function must be valid.
        pub unsafe fn leaf_post_order<T>(node: NonNull<Node<T>>) -> NonNull<Node<T>> {
            unsafe {
                if let Some(left) = node.as_ref().left {
                    leaf_post_order(left)
                } else if let Some(right) = node.as_ref().right {
                    leaf_post_order(right)
                } else {
                    node
                }
            }
        }

        /// Iterator over a tree in post-order (`Left -> Right -> Node`, or `LRN`).
        ///
        /// Post-order traversal visits both subtrees before the current node.
        pub struct IterPostOrder<'a, T> {
            current_node: Link<T>,
            count: usize,
            _boo: PhantomData<&'a T>,
        }

        impl<'a, T> IterPostOrder<'a, T> {
            /// Creates a post-order iterator starting at the first post-order node.
            pub(crate) fn new(root: Link<T>, count: usize) -> Self {
                Self {
                    current_node: root,
                    count,
                    _boo: PhantomData,
                }
            }
        }

        impl<'a, T> Iterator for IterPostOrder<'a, T> {
            type Item = &'a T;

            fn next(&mut self) -> Option<Self::Item> {
                if self.count == 0 {
                    return None;
                }

                let node = self.current_node?;

                unsafe {
                    let value = &node.as_ref().value;
                    self.current_node = successor_of_node_post_order(node);
                    self.count -= 1;
                    Some(value)
                }
            }

            fn size_hint(&self) -> (usize, Option<usize>) {
                (self.count, Some(self.count))
            }
        }
    }

    /// Breadth-First Search
    mod bfs {
        use super::{Node, NonNull};
        use std::collections::VecDeque;

        /// Appends tree values to `ret` in breadth-first / level-order.
        pub fn iter_level_order_impl<T>(root: NonNull<Node<T>>, ret: &mut Vec<&T>) {
            let mut deque: VecDeque<NonNull<Node<T>>> = VecDeque::new();
            unsafe {
                deque.push_back(root);
                let mut node: NonNull<Node<T>>;
                while !deque.is_empty() {
                    node = deque.pop_front().unwrap();
                    ret.push(&node.as_ref().value);
                    if let Some(left) = node.as_ref().left {
                        deque.push_back(left);
                    }
                    if let Some(right) = node.as_ref().right {
                        deque.push_back(right);
                    }
                }
            }
        }
    }

    pub(crate) use bfs::iter_level_order_impl;
}

/// Internal node representation used by the Red-Black Tree.
///
/// Nodes are allocated on the heap and connected using [`NonNull`] pointers.
/// The tree owns the allocated nodes and is responsible for releasing them.
///
/// `Node` and [`Link`] are crate-private implementation details and are not
/// exposed through the public API.
pub mod node{

    use std::ptr::NonNull;

    /// A single node in the Red-Black Tree.
    ///
    /// Each node stores:
    ///
    /// - a link to its left child;
    /// - a link to its right child;
    /// - a link to its parent;
    /// - its Red-Black color;
    /// - the stored value.
    ///
    /// Tree links are represented by [`Link<T>`], which is an
    /// `Option<NonNull<Node<T>>>`.
    ///
    /// A `None` link represents the absence of a parent or child, while
    /// `Some(pointer)` refers to another allocated node.
    ///
    /// Memory ownership is managed by [`crate::RedBlackTree`]. The pointers stored
    /// here are non-owning links between nodes.
    #[derive(Debug)]
    pub(crate) struct Node<T> {
        /// Left child of this node.
        pub(crate) left: Link<T>,

        /// Right child of this node.
        pub(crate) right: Link<T>,

        /// Parent of this node.
        ///
        /// The root node has no parent.
        pub(crate) parent: Link<T>,

        /// Red-Black color of the node.
        ///
        /// `true` means red and `false` means black.
        pub(crate) is_red: bool,

        /// Value stored in this node.
        pub(crate) value: T,
    }

    /// A link between nodes in the tree.
    ///
    /// `None` represents a missing parent or child.
    ///
    /// `Some(ptr)` contains a non-null pointer to another allocated [`Node`].
    ///
    /// Using `Option<NonNull<Node<T>>>` allows the implementation to represent
    /// nullable tree links while keeping direct pointer-based navigation between
    /// parents and children.
    pub(crate) type Link<T> = Option<NonNull<Node<T>>>;

    impl<T: Default> Node<T> {
        /// Creates the sentinel head node together with the initial tree root.
        ///
        /// The sentinel does not represent a value stored by the user. Its
        /// `value` field is initialized with [`Default::default`] and its left
        /// child becomes the first actual node in the tree.
        ///
        /// The initial root node is created as black, as required by the
        /// Red-Black Tree invariants.
        ///
        /// # Returns
        ///
        /// A link to the newly allocated sentinel node.
        ///
        /// # Implementation
        ///
        /// Both the sentinel and the root node are allocated on the heap.
        /// Ownership of these allocations is transferred to the tree and later
        /// recovered when the tree releases its nodes.
        pub(crate) fn new_fixed_head(value: T) -> Link<T> {
            let fixed_head = Box::into_non_null(Box::new(Self {
                left: None,
                right: None,
                parent: None,
                is_red: false,
                value: T::default(),
            }));
            unsafe {
                (*fixed_head.as_ptr()).left = Node::new_black(value);
            }
            Some(fixed_head)
        }
    }

    impl<T> Node<T> {
        /// Allocates a new black node.
        ///
        /// The node is created without a parent or children.
        ///
        /// # Returns
        ///
        /// A non-null link to the newly allocated node.
        ///
        /// The allocation becomes owned by the tree and must eventually be
        /// released by the tree implementation.
        pub(crate) fn new_black(value: T) -> Link<T> {
            let new = Box::into_non_null(Box::new(Self {
                left: None,
                right: None,
                parent: None,
                is_red: false,
                value,
            }));

            Some(new)
        }

        /// Allocates a new red node with the specified parent.
        ///
        /// Newly inserted Red-Black Tree nodes are initially red. The balancing
        /// algorithm may later recolor the node or rotate the surrounding
        /// subtree.
        ///
        /// The new node has no children.
        ///
        /// # Parameters
        ///
        /// - `value` — value stored in the node.
        /// - `parent` — non-null pointer to the node's parent.
        ///
        /// # Returns
        ///
        /// A non-null link to the newly allocated node.
        ///
        /// The allocation becomes owned by the tree and must eventually be
        /// released by the tree implementation.
        pub(crate) fn new_red(value: T, parent: NonNull<Node<T>>) -> Link<T> {
            let new = Box::into_non_null(Box::new(Self {
                left: None,
                right: None,
                parent: Some(parent),
                is_red: true,
                value,
            }));

            Some(new)
        }
    }
}


pub mod validation{
    use crate::node::Link;
    use crate::tree::RedBlackTree;

    impl<T: Ord + Default> RedBlackTree<T> {
        // red-red violations,
        // min black-height,
        // max black-height,
        // BST ordering,
        // parent links,
        // reachable node count
        unsafe fn validate(
            node: &Link<T>,
            expected_parent: Link<T>,
            parent_is_red: bool,
            black_height: usize,
            min: Option<&T>,
            max: Option<&T>,
        ) -> (usize, usize, usize, bool, bool, usize) {
            unsafe {
                if let Some(n) = node {
                    let value = &n.as_ref().value;

                    // 1. Check parent
                    let parent_valid = match (n.as_ref().parent, expected_parent) {
                        (None, None) => true,

                        (Some(actual), Some(expected)) => {
                            std::ptr::eq(actual.as_ptr(), expected.as_ptr())
                        }

                        _ => false,
                    };

                    // 2. Check BST ordering
                    if let Some(min) = min
                        && value <= min
                    {
                        return (0, 0, 0, false, parent_valid, 1);
                    }

                    if let Some(max) = max
                        && value >= max
                    {
                        return (0, 0, 0, false, parent_valid, 1);
                    }

                    let is_red = n.as_ref().is_red;

                    // 3. A red node cannot have a red parent.
                    let red_red = if parent_is_red && is_red { 1 } else { 0 };

                    // 4. Black height
                    let black_height = if is_red {
                        black_height
                    } else {
                        black_height + 1
                    };

                    let left = Self::validate(
                        &n.as_ref().left,
                        Some(*n),
                        is_red,
                        black_height,
                        min,
                        Some(value),
                    );

                    let right = Self::validate(
                        &n.as_ref().right,
                        Some(*n),
                        is_red,
                        black_height,
                        Some(value),
                        max,
                    );

                    (
                        red_red + left.0 + right.0,
                        std::cmp::min(left.1, right.1),
                        std::cmp::max(left.2, right.2),
                        left.3 && right.3,
                        parent_valid && left.4 && right.4,
                        1 + left.5 + right.5,
                    )
                } else {
                    (0, black_height, black_height, true, true, 0)
                }
            }
        }

        pub fn is_valid(&self) -> bool {
            unsafe {
                // tree is empty
                if self.count == 0 {
                    return match self.fixed_head {
                        None => true,

                        Some(fixed_head) => (*fixed_head.as_ptr()).left.is_none(),
                    };
                }

                // count > 0, so sentinel must exist.
                let Some(fixed_head) = self.fixed_head else {
                    return false;
                };

                // And root must exist.
                let root_link = (*fixed_head.as_ptr()).left;

                let Some(root) = root_link else {
                    return false;
                };

                // Root is always BLACK
                if root.as_ref().is_red {
                    return false;
                }

                // Root has no parent
                if root.as_ref().parent.is_some() {
                    return false;
                }

                let result = Self::validate(&root_link, None, false, 0, None, None);

                let red_red = result.0;
                let black_height_min = result.1;
                let black_height_max = result.2;
                let bst_valid = result.3;
                let parents_valid = result.4;
                let reachable_nodes = result.5;

                red_red == 0
                    && black_height_min == black_height_max
                    && bst_valid
                    && parents_valid
                    && reachable_nodes == self.count
            }
        }
    }
}


pub mod tree{
    use std::cmp::Ordering;
    use std::fmt::{Debug, Display};

    use crate::node::{Link, Node};

    use std::marker::PhantomData;
    use std::ptr::NonNull;

    use crate::iter::{IterInOrder, Range, leftmost_child_in_order, successor_of_node_in_order};

    use crate::iter::{
        IterReverseInOrder, rightmost_child_reverse_in_order, successor_of_node_reverse_in_order,
    };

    use crate::iter::{IterPreOrder, successor_of_node_pre_order};

    use crate::iter::{IterPostOrder, leaf_post_order, successor_of_node_post_order};

    use crate::iter::iter_level_order_impl;

    /// A self-balancing Red-Black Tree.
    ///
    /// `RedBlackTree` stores unique values in sorted order.
    ///
    /// Insert, lookup and removal operations have logarithmic
    /// expected tree height due to Red-Black Tree balancing.
    ///
    /// # Examples
    ///
    /// ```
    /// use rbtree_extended::RedBlackTree;
    ///
    /// let mut tree = RedBlackTree::new();
    ///
    /// tree.insert(3);
    /// tree.insert(1);
    /// tree.insert(2);
    ///
    /// assert_eq!(tree.len(), 3);
    /// assert!(tree.contains(&2));
    /// ```
    pub struct RedBlackTree<T: Ord + Default> {
        pub(crate) fixed_head: Link<T>,
        pub(crate) count: usize,
        _marker: PhantomData<T>,
    }

    enum OperationPut {
        Left,
        Right,
        FlipColors,
        Nothing,
    }

    enum OperationRemove {
        RedLeaf,
        BlackLeaf,
        NodeWithChildren,
        BlackNodeWithRedLeaf,
    }

    enum OperationRemoveBlackLeaf {
        LeftRedABlackBRedCleaf,                      // 2.1.1.1
        RightRedABlackBRedCleaf,                     // 2.1.1.2
        LeftRedABlackBleaf,                          // 2.1.2.1
        RightRedABlackBleaf,                         // 2.1.2.2
        BlackARedBWithBlackChildrenLeaf,             // 2.2.4
        BlackARedBWithBlackChildrenRightHaveRedLeaf, // 2.2.1
        BlackALeftBlackBRedDleaf,                    // 2.3.1.1
        BlackARightBlackBRedDleaf,                   // 2.3.1.2
        BlackALeftBlackBleaf,                        // 2.3.2.1
        BlackARightBlackBleaf,                       // 2.3.2.2
        Root,
        Unimplemented,
    }

    impl<T: Ord + Default + Display> RedBlackTree<T> {
        /// Exports the tree in Graphviz DOT format.
        ///
        /// The returned string can be rendered using Graphviz-compatible tools.
        ///
        /// An empty tree produces a valid empty DOT graph.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.insert(10);
        /// tree.insert(5);
        /// tree.insert(20);
        ///
        /// let dot = tree.to_dot();
        ///
        /// println!("{dot}");
        /// ```
        pub fn to_dot(&self) -> String {
            unsafe {
                let Some(fixed_head) = self.fixed_head else {
                    return "digraph Tree {}".into();
                };

                let Some(root) = (*fixed_head.as_ptr()).left else {
                    return "digraph Tree {}".into();
                };

                format!(
                    "\ndigraph Tree {{\n\tratio = fill;\n\tnode [style=filled fontcolor=\"white\"];\n{}}}",
                    helper_display_tree(root)
                )
            }
        }
    }

    impl<T: Ord + Default> RedBlackTree<T> {
        /// Creates an empty Red-Black Tree.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let tree = RedBlackTree::<i32>::new();
        ///
        /// assert!(tree.is_empty());
        /// ```
        pub fn new() -> Self {
            Self {
                fixed_head: None,
                count: 0,
                _marker: PhantomData,
            }
        }

        /// Returns the number of values stored in the tree.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.insert(10);
        /// tree.insert(20);
        ///
        /// assert_eq!(tree.len(), 2);
        /// ```
        pub fn len(&self) -> usize {
            self.count
        }

        /// Returns `true` if the tree contains no values.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::<i32>::new();
        /// assert!(tree.is_empty());
        ///
        /// tree.insert(10);
        /// assert!(!tree.is_empty());
        /// ```
        pub fn is_empty(&self) -> bool {
            self.count == 0
        }

        /// Removes all values from the tree.
        ///
        /// After calling `clear`, the tree is empty and can be reused.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([1, 2, 3]);
        ///
        /// tree.clear();
        ///
        /// assert!(tree.is_empty());
        /// assert_eq!(tree.len(), 0);
        /// ```
        pub fn clear(&mut self) {
            unsafe {
                if let Some(fixed_head) = self.fixed_head {
                    let root = (*fixed_head.as_ptr()).left;

                    (*fixed_head.as_ptr()).left = None;

                    self.remove_tree(root);
                }

                debug_assert_eq!(self.count, 0);
            }
        }

        /// Returns the smallest value in the tree.
        ///
        /// Returns `None` if the tree is empty.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([8, 3, 10, 1]);
        ///
        /// assert_eq!(tree.first(), Some(&1));
        /// ```
        pub fn first(&self) -> Option<&T> {
            self.minimum()
        }

        /// Returns the largest value in the tree.
        ///
        /// Returns `None` if the tree is empty.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([8, 3, 10, 14]);
        ///
        /// assert_eq!(tree.last(), Some(&14));
        /// ```
        pub fn last(&self) -> Option<&T> {
            self.maximum()
        }

        fn minimum(&self) -> Option<&T> {
            unsafe {
                let root = self.get_root()?;
                let node = self.find_min(root);
                Some(&node.as_ref().value)
            }
        }

        fn maximum(&self) -> Option<&T> {
            unsafe {
                let root = self.get_root()?;
                let node = self.find_max(root);

                Some(&node.as_ref().value)
            }
        }

        /// Returns the height of the tree.
        ///
        /// An empty tree has height `0`.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// assert_eq!(tree.height(), 0);
        ///
        /// tree.insert(10);
        /// assert_eq!(tree.height(), 1);
        /// ```
        pub fn height(&self) -> usize {
            unsafe fn height_from<T>(node: Link<T>) -> usize {
                unsafe {
                    match node {
                        None => 0,

                        Some(node) => {
                            let left_height = height_from(node.as_ref().left);
                            let right_height = height_from(node.as_ref().right);

                            1 + left_height.max(right_height)
                        }
                    }
                }
            }

            unsafe { height_from(self.get_root()) }
        }

        /// Returns `true` if the tree contains `value`.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([1, 3, 5]);
        ///
        /// assert!(tree.contains(&3));
        /// assert!(!tree.contains(&4));
        /// ```
        pub fn contains(&self, value: &T) -> bool {
            !find_node(self.get_root(), value).is_none()
        }

        /// Inserts a value into the tree.
        ///
        /// Returns `true` if the value was inserted.
        ///
        /// Returns `false` if the value already exists.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        ///
        /// assert!(tree.insert(10));
        /// assert!(!tree.insert(10));
        /// ```
        pub fn insert(&mut self, value: T) -> bool {
            unsafe {
                if let Some(fixed_head) = self.fixed_head {
                    if (*fixed_head.as_ptr()).left.is_none() {
                        (*fixed_head.as_ptr()).left = Node::new_black(value);
                        self.count += 1;
                        return true;
                    }

                    let parent = self.find_put_parent_candidate(self.get_root(), &value);

                    if let Some(parent) = parent {
                        if self.attach_node(parent, value) {
                            self.put_balancing(parent);
                        } else {
                            return false;
                        }
                    } else {
                        return false;
                    }
                } else {
                    self.fixed_head = Node::new_fixed_head(value);
                }

                self.count += 1;
                true
            }
        }

        /// Removes a value from the tree.
        ///
        /// Returns `true` if the value existed and was removed.
        ///
        /// Use [`RedBlackTree::take`] when ownership of the removed value is needed.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.insert(10);
        ///
        /// assert!(tree.remove(&10));
        /// assert!(!tree.contains(&10));
        /// assert!(!tree.remove(&10));
        /// ```
        pub fn remove(&mut self, value: &T) -> bool {
            self.take(value).is_some()
        }

        /// Inserts `value` into the tree, replacing an existing equal value.
        ///
        /// If the tree already contains a value that compares equal to `value`,
        /// the existing value is replaced and returned.
        ///
        /// If no equal value exists, `value` is inserted and `None` is returned.
        ///
        /// This is especially useful for custom types whose [`Ord`] implementation
        /// compares only a key field.
        ///
        /// # Examples
        ///
        /// ```
        /// use std::cmp::Ordering;
        /// use rbtree_extended::RedBlackTree;
        ///
        /// #[derive(Debug, Default)]
        /// struct User {
        ///     id: u32,
        ///     name: String,
        /// }
        ///
        /// impl PartialEq for User {
        ///     fn eq(&self, other: &Self) -> bool {
        ///         self.id == other.id
        ///     }
        /// }
        ///
        /// impl Eq for User {}
        ///
        /// impl PartialOrd for User {
        ///     fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        ///         Some(self.cmp(other))
        ///     }
        /// }
        ///
        /// impl Ord for User {
        ///     fn cmp(&self, other: &Self) -> Ordering {
        ///         self.id.cmp(&other.id)
        ///     }
        /// }
        ///
        /// let mut users = RedBlackTree::new();
        ///
        /// users.insert(User {
        ///     id: 1,
        ///     name: "Alice".into(),
        /// });
        ///
        /// let old = users.replace(User {
        ///     id: 1,
        ///     name: "Bob".into(),
        /// });
        ///
        /// assert_eq!(old.unwrap().name, "Alice");
        /// assert_eq!(users.first().unwrap().name, "Bob");
        /// ```
        pub fn replace(&mut self, value: T) -> Option<T> {
            unsafe {
                if let Some(mut node) = find_node(self.get_root(), &value) {
                    return Some(std::mem::replace(&mut node.as_mut().value, value));
                }
            }

            self.insert(value);

            None
        }

        unsafe fn take_node(&mut self, mut node: NonNull<Node<T>>) -> Option<T> {
            unsafe {
                // Save the original value before the internal removal algorithm
                // starts swapping values between nodes.
                let removed_value = std::mem::take(&mut node.as_mut().value);

                if !self.remove_node(node) {
                    return None;
                }

                self.count -= 1;

                Some(removed_value)
            }
        }

        /// Removes and returns the value equal to `value`.
        ///
        /// Returns `None` if the value is not present in the tree.
        ///
        /// Unlike [`RedBlackTree::remove`], this method gives ownership of the
        /// removed value back to the caller.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([10, 5, 20]);
        ///
        /// assert_eq!(tree.take(&10), Some(10));
        /// assert!(!tree.contains(&10));
        /// assert_eq!(tree.take(&100), None);
        /// ```
        pub fn take(&mut self, value: &T) -> Option<T> {
            if self.is_empty() {
                return None;
            }

            unsafe {
                let node = find_node(self.get_root(), value)?;
                self.take_node(node)
            }
        }

        /// Retains only the values specified by the predicate.
        ///
        /// In other words, removes every value for which `f(&value)` returns `false`.
        ///
        /// The predicate receives a shared reference to each stored value.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([1, 2, 3, 4, 5, 6]);
        ///
        /// tree.retain(|value| value % 2 == 0);
        ///
        /// assert_eq!(
        ///     tree.iter().copied().collect::<Vec<_>>(),
        ///     vec![2, 4, 6]
        /// );
        /// ```
        ///
        /// Retaining no values empties the tree:
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([1, 2, 3]);
        ///
        /// tree.retain(|_| false);
        ///
        /// assert!(tree.is_empty());
        /// ```
        pub fn retain<F>(&mut self, mut f: F)
        where
            F: FnMut(&T) -> bool,
        {
            let mut retained = Self::new();

            while let Some(value) = self.pop_first() {
                if f(&value) {
                    retained.insert(value);
                }
            }

            *self = retained;
        }

        /// Removes and returns the smallest value in the tree.
        ///
        /// Returns `None` if the tree is empty.
        ///
        /// This operation is useful when values need to be processed in
        /// ascending order.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([8, 3, 10, 1, 6]);
        ///
        /// assert_eq!(tree.pop_first(), Some(1));
        /// assert_eq!(tree.pop_first(), Some(3));
        /// assert_eq!(tree.len(), 3);
        /// ```
        pub fn pop_first(&mut self) -> Option<T> {
            unsafe {
                let root = self.get_root()?;
                let node = self.find_min(root);

                self.take_node(node)
            }
        }

        /// Removes and returns the largest value in the tree.
        ///
        /// Returns `None` if the tree is empty.
        ///
        /// This operation can be used to implement a priority queue where the
        /// greatest value represents the highest priority.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([8, 3, 10, 1, 6]);
        ///
        /// assert_eq!(tree.pop_last(), Some(10));
        /// assert_eq!(tree.pop_last(), Some(8));
        /// assert_eq!(tree.len(), 3);
        /// ```
        pub fn pop_last(&mut self) -> Option<T> {
            unsafe {
                let root = self.get_root()?;
                let node = self.find_max(root);

                self.take_node(node)
            }
        }

        /// Returns a reference to the stored value equal to `value`.
        ///
        /// Returns `None` if no matching value exists.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([1, 3, 5]);
        ///
        /// assert_eq!(tree.get(&3), Some(&3));
        /// assert_eq!(tree.get(&4), None);
        /// ```
        pub fn get(&self, value: &T) -> Option<&T> {
            unsafe {
                let node = find_node(self.get_root(), value)?;
                Some(&node.as_ref().value)
            }
        }

        /// Returns the next greater value in sorted order.
        ///
        /// Returns `None` if `value` is not present or if it is the largest value.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([1, 3, 5, 7]);
        ///
        /// assert_eq!(tree.successor(&3), Some(&5));
        /// assert_eq!(tree.successor(&7), None);
        /// ```
        pub fn successor(&self, value: &T) -> Option<&T> {
            unsafe {
                let node = find_node(self.get_root(), value)?;

                // Case 1:
                // there is a right subtree - successor = minimum element on the right
                if let Some(right) = node.as_ref().right {
                    let successor = self.find_min(right);
                    return Some(&successor.as_ref().value);
                }

                // Case 2:
                // there is no right subtree
                // Move up while the current node is a right child
                let mut current = node;
                let mut parent = current.as_ref().parent;

                while let Some(p) = parent {
                    if let Some(left) = p.as_ref().left
                        && std::ptr::eq(left.as_ptr(), current.as_ptr())
                    {
                        return Some(&p.as_ref().value);
                    }

                    current = p;
                    parent = p.as_ref().parent;
                }

                None
            }
        }

        /// Returns the previous smaller value in sorted order.
        ///
        /// Returns `None` if `value` is not present or if it is the smallest value.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([1, 3, 5, 7]);
        ///
        /// assert_eq!(tree.predecessor(&5), Some(&3));
        /// assert_eq!(tree.predecessor(&1), None);
        /// ```
        pub fn predecessor(&self, value: &T) -> Option<&T> {
            unsafe {
                let node = find_node(self.get_root(), value)?;

                // Case 1:
                // there is a left subtree - predecessor = maximum element on the left
                if let Some(left) = node.as_ref().left {
                    let predecessor = self.find_max(left);
                    return Some(&predecessor.as_ref().value);
                }

                // Case 2:
                // there is no left subtree
                // Move up while the current node is a left child
                let mut current = node;
                let mut parent = current.as_ref().parent;

                while let Some(p) = parent {
                    if let Some(right) = p.as_ref().right
                        && std::ptr::eq(right.as_ptr(), current.as_ptr())
                    {
                        return Some(&p.as_ref().value);
                    }

                    current = p;
                    parent = p.as_ref().parent;
                }

                None
            }
        }

        /// Returns the first value greater than or equal to `value`.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([1, 3, 6, 8]);
        ///
        /// assert_eq!(tree.lower_bound(&5), Some(&6));
        /// assert_eq!(tree.lower_bound(&6), Some(&6));
        /// ```
        pub fn lower_bound(&self, value: &T) -> Option<&T> {
            unsafe {
                let mut current = self.get_root();
                let mut candidate: Link<T> = None;

                while let Some(node) = current {
                    match node.as_ref().value.cmp(value) {
                        Ordering::Less => {
                            current = node.as_ref().right;
                        }

                        Ordering::Equal => {
                            return Some(&node.as_ref().value);
                        }

                        Ordering::Greater => {
                            candidate = Some(node);
                            current = node.as_ref().left;
                        }
                    }
                }

                candidate.map(|node| &node.as_ref().value)
            }
        }

        /// Returns the first value strictly greater than `value`.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([1, 3, 6, 8]);
        ///
        /// assert_eq!(tree.upper_bound(&6), Some(&8));
        /// assert_eq!(tree.upper_bound(&8), None);
        /// ```
        pub fn upper_bound(&self, value: &T) -> Option<&T> {
            unsafe {
                let mut current = self.get_root();
                let mut candidate: Link<T> = None;

                while let Some(node) = current {
                    match node.as_ref().value.cmp(value) {
                        Ordering::Less | Ordering::Equal => {
                            current = node.as_ref().right;
                        }
                        Ordering::Greater => {
                            candidate = Some(node);
                            current = node.as_ref().left;
                        }
                    }
                }

                candidate.map(|node| &node.as_ref().value)
            }
        }

        /// Returns an iterator over values in the inclusive range `[min, max]`.
        ///
        /// Values are yielded in ascending order.
        ///
        /// The iterator is lazy: values are produced only as they are requested,
        /// rather than being collected into an intermediate `Vec`.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([1, 3, 5, 7, 9, 11]);
        ///
        /// let values: Vec<_> = tree
        ///     .range(&3, &9)
        ///     .copied()
        ///     .collect();
        ///
        /// assert_eq!(values, vec![3, 5, 7, 9]);
        /// ```
        pub fn range(&self, min: &T, max: &T) -> Range<'_, T> {
            Range::new(self.get_root(), min, max)
        }

        /// Returns the next value in an in-order (`LNR`) traversal.
        ///
        /// For a binary search tree, in-order traversal visits values in ascending order.
        ///
        /// Returns `None` if `value` is not present or has no successor in this traversal.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([4, 2, 6, 1, 3, 5, 7]);
        ///
        /// assert_eq!(tree.successor_dfs_in_order(4), Some(&5));
        /// ```
        pub fn successor_dfs_in_order(&self, value: T) -> Option<&T> {
            unsafe {
                let node = find_node(self.get_root(), &value);
                if let Some(n) = node
                    && let Some(nodesucc) = successor_of_node_in_order(n)
                {
                    return Some(&nodesucc.as_ref().value);
                }
                None
            }
        }

        /// Returns the next value in reverse in-order (`RNL`) traversal.
        ///
        /// For a binary search tree, reverse in-order traversal visits values in
        /// descending order.
        ///
        /// Returns `None` if `value` is not present or has no successor in this traversal.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([4, 2, 6, 1, 3, 5, 7]);
        ///
        /// assert_eq!(tree.successor_dfs_reverse_in_order(6), Some(&5));
        /// ```
        pub fn successor_dfs_reverse_in_order(&self, value: T) -> Option<&T> {
            unsafe {
                if let Some(node) = find_node(self.get_root(), &value)
                    && let Some(next) = successor_of_node_reverse_in_order(node)
                {
                    return Some(&next.as_ref().value);
                }
                None
            }
        }

        /// Returns the next value in post-order (`LRN`) traversal.
        ///
        /// Post-order visits the left subtree, then the right subtree,
        /// and finally the current node.
        ///
        /// Returns `None` if `value` is not present or has no successor in this traversal.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([4, 2, 6, 1, 3, 5, 7]);
        ///
        /// // Post-order: 1, 3, 2, 5, 7, 6, 4
        /// assert_eq!(tree.successor_dfs_post_order(3), Some(&2));
        /// assert_eq!(tree.successor_dfs_post_order(2), Some(&5));
        /// assert_eq!(tree.successor_dfs_post_order(4), None);
        /// ```
        pub fn successor_dfs_post_order(&self, value: T) -> Option<&T> {
            unsafe {
                if let Some(n) = find_node(self.get_root(), &value)
                    && let Some(nodesucc) = successor_of_node_post_order(n)
                {
                    return Some(&nodesucc.as_ref().value);
                }
                None
            }
        }

        /// Returns the next value in pre-order (`NLR`) traversal.
        ///
        /// Pre-order visits the current node first, followed by the left and right
        /// subtrees.
        ///
        /// Returns `None` if `value` is not present or has no successor in this traversal.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([4, 2, 6, 1, 3, 5, 7]);
        ///
        /// let first = *tree.iter_preorder().next().unwrap();
        /// assert_eq!(tree.successor_dfs_pre_order(first), tree.iter_preorder().nth(1));
        /// ```
        pub fn successor_dfs_pre_order(&self, value: T) -> Option<&T> {
            unsafe {
                if let Some(n) = find_node(self.get_root(), &value)
                    && let Some(nodesucc) = successor_of_node_pre_order(n)
                {
                    return Some(&nodesucc.as_ref().value);
                }
                None
            }
        }

        fn get_root(&self) -> Link<T> {
            if let Some(fixed_head) = self.fixed_head {
                unsafe { (*fixed_head.as_ptr()).left }
            } else {
                None
            }
        }

        unsafe fn operation_remove(&self, node_x: &NonNull<Node<T>>) -> OperationRemove {
            unsafe {
                if node_x.as_ref().is_red
                    && node_x.as_ref().left.is_none()
                    && node_x.as_ref().right.is_none()
                {
                    return OperationRemove::RedLeaf;
                }
                if node_x.as_ref().is_red
                    && node_x.as_ref().left.is_some()
                    && node_x.as_ref().right.is_some()
                {
                    return OperationRemove::NodeWithChildren;
                }
                if !node_x.as_ref().is_red {
                    if node_x.as_ref().left.is_some() && node_x.as_ref().right.is_some() {
                        return OperationRemove::NodeWithChildren;
                    } else if node_x.as_ref().left.is_some() && node_x.as_ref().right.is_none() {
                        if let Some(left) = node_x.as_ref().left
                            && left.as_ref().is_red
                            && left.as_ref().left.is_none()
                            && left.as_ref().right.is_none()
                        {
                            return OperationRemove::BlackNodeWithRedLeaf;
                        }
                    } else if node_x.as_ref().left.is_none() && node_x.as_ref().right.is_none() {
                        return OperationRemove::BlackLeaf;
                    }
                }
                panic!();
            }
        }

        unsafe fn operation_remove_black_leaf(
            &self,
            node_x: &NonNull<Node<T>>,
        ) -> OperationRemoveBlackLeaf {
            unsafe {
                if let Some(node_a) = node_x.as_ref().parent {
                    if node_a.as_ref().is_red {
                        if let Some(node_b) = node_a.as_ref().left
                            && !std::ptr::eq(node_b.as_ptr(), node_x.as_ptr())
                            && !node_b.as_ref().is_red
                        {
                            if let Some(node_c) = node_b.as_ref().left
                                && node_c.as_ref().is_red
                            {
                                return OperationRemoveBlackLeaf::LeftRedABlackBRedCleaf;
                                // 2.1.1.1
                            }

                            // sibling B is black and its left child is either absent or also black
                            return OperationRemoveBlackLeaf::LeftRedABlackBleaf;
                            // 2.1.2.1
                        }

                        if let Some(node_b) = node_a.as_ref().right
                            && !std::ptr::eq(node_b.as_ptr(), node_x.as_ptr())
                            && !node_b.as_ref().is_red
                        {
                            if let Some(node_c) = node_b.as_ref().left
                                && node_c.as_ref().is_red
                            {
                                return OperationRemoveBlackLeaf::RightRedABlackBRedCleaf;
                                // 2.1.1.2
                            }

                            // sibling B is black and its left child is either absent or also black
                            return OperationRemoveBlackLeaf::RightRedABlackBleaf;
                            // 2.1.2.2
                        }
                    } else {
                        if let Some(node_b) = node_a.as_ref().left
                            && !std::ptr::eq(node_b.as_ptr(), node_x.as_ptr())
                        {
                            if node_b.as_ref().is_red && node_b.as_ref().right.is_some() {
                                let node_c = node_b.as_ref().right.unwrap();
                                if !node_c.as_ref().is_red {
                                    if node_c.as_ref().left.is_some()
                                        && let Some(node_d) = node_c.as_ref().left
                                        && node_d.as_ref().is_red
                                    {
                                        return OperationRemoveBlackLeaf::BlackARedBWithBlackChildrenRightHaveRedLeaf;
                                        // 2.2.1
                                    }
                                    return OperationRemoveBlackLeaf::BlackARedBWithBlackChildrenLeaf;
                                    // 2.2.2
                                }
                            }
                            if !node_b.as_ref().is_red
                                && node_b.as_ref().left.is_some()
                                && let Some(node_d) = node_b.as_ref().left
                                && node_d.as_ref().is_red
                            {
                                return OperationRemoveBlackLeaf::BlackALeftBlackBRedDleaf;
                                // 2.3.1.1
                            }
                            if !node_b.as_ref().is_red {
                                return OperationRemoveBlackLeaf::BlackALeftBlackBleaf;
                                // 2.3.2.1
                            }
                        }
                        if let Some(node_b) = node_a.as_ref().right
                            && !std::ptr::eq(node_b.as_ptr(), node_x.as_ptr())
                        {
                            if !node_b.as_ref().is_red
                                && node_b.as_ref().left.is_some()
                                && let Some(node_d) = node_b.as_ref().left
                                && node_d.as_ref().is_red
                            {
                                return OperationRemoveBlackLeaf::BlackARightBlackBRedDleaf;
                                // 2.3.1.2
                            }
                            if !node_b.as_ref().is_red {
                                return OperationRemoveBlackLeaf::BlackARightBlackBleaf;
                                // 2.3.2.2
                            }
                        }
                    }
                } else {
                    return OperationRemoveBlackLeaf::Root;
                }
                OperationRemoveBlackLeaf::Unimplemented
            }
        }

        unsafe fn remove_black_leaf(&mut self, node_x: NonNull<Node<T>>) -> bool {
            unsafe {
                let mut next = node_x;
                let mut removed = false;
                loop {
                    match self.operation_remove_black_leaf(&next) {
                        OperationRemoveBlackLeaf::LeftRedABlackBRedCleaf => {
                            self.remove_black_leaf_2_1_1_1_balancing(&next);
                            if !removed {
                                removed = self.remove_leaf(node_x);
                            }
                            break;
                        }
                        OperationRemoveBlackLeaf::RightRedABlackBRedCleaf => {
                            self.remove_black_leaf_2_1_1_2_balancing(&next);
                            if !removed {
                                removed = self.remove_leaf(node_x);
                            }
                            break;
                        }
                        OperationRemoveBlackLeaf::LeftRedABlackBleaf => {
                            self.remove_black_leaf_2_1_2_1_balancing(&next);
                            if !removed {
                                removed = self.remove_leaf(node_x);
                            }
                            break;
                        }
                        OperationRemoveBlackLeaf::RightRedABlackBleaf => {
                            self.remove_black_leaf_2_1_2_2_balancing(&next);
                            if !removed {
                                removed = self.remove_leaf(node_x);
                            }
                            break;
                        }
                        OperationRemoveBlackLeaf::BlackARedBWithBlackChildrenRightHaveRedLeaf => {
                            self.remove_black_leaf_2_2_1_balancing(&next);
                            if !removed {
                                removed = self.remove_leaf(node_x);
                            }
                            break;
                        }
                        OperationRemoveBlackLeaf::BlackARedBWithBlackChildrenLeaf => {
                            self.remove_black_leaf_2_2_2_balancing(&next);
                            if !removed {
                                removed = self.remove_leaf(node_x);
                            }
                            break;
                        }
                        OperationRemoveBlackLeaf::BlackALeftBlackBRedDleaf => {
                            self.remove_black_leaf_2_3_1_1_balancing(&next);
                            if !removed {
                                removed = self.remove_leaf(node_x);
                            }
                            break;
                        }
                        OperationRemoveBlackLeaf::BlackARightBlackBRedDleaf => {
                            self.remove_black_leaf_2_3_1_2_balancing(&next);
                            if !removed {
                                removed = self.remove_leaf(node_x);
                            }
                            break;
                        }
                        OperationRemoveBlackLeaf::BlackALeftBlackBleaf => {
                            next = self.remove_black_leaf_2_3_2_1_balancing(&next);
                            if !removed {
                                removed = self.remove_leaf(node_x);
                            }
                        }
                        OperationRemoveBlackLeaf::BlackARightBlackBleaf => {
                            next = self.remove_black_leaf_2_3_2_2_balancing(&next);
                            if !removed {
                                removed = self.remove_leaf(node_x);
                            }
                        }
                        OperationRemoveBlackLeaf::Root => {
                            if !removed {
                                // We get here when the node_x being deleted is root
                                if let Some(fixed_head) = self.fixed_head {
                                    (*fixed_head.as_ptr()).left = None;
                                }
                                let _ = Box::from_raw(node_x.as_ptr());
                                removed = true;
                            }
                            break;
                        }
                        OperationRemoveBlackLeaf::Unimplemented => {
                            panic!("unimplemented black leaf removal case");
                        }
                    }
                }
                removed
            }
        }

        /// 2.1.1.1 remove black X
        ///
        /// ```text
        ///             P            P
        ///            //           //
        ///            A            B
        ///           / \          / \
        ///          B   X   =>   C   A
        ///         //\              /
        ///        C   D            D
        /// ```
        unsafe fn remove_black_leaf_2_1_1_1_balancing(&mut self, node_x: &NonNull<Node<T>>) {
            unsafe {
                let node_a = (*node_x.as_ptr()).parent.unwrap();
                let node_b = (*node_a.as_ptr()).left.unwrap();
                let node_d = (*node_b.as_ptr()).right;
                (*node_b.as_ptr()).parent = (*node_a.as_ptr()).parent;
                if let Some(ref mut parent) = (*node_b.as_ptr()).parent {
                    (*parent.as_ptr()).left = Some(node_b);
                }
                (*node_a.as_ptr()).left = node_d;
                if let Some(n_d) = node_d {
                    (*n_d.as_ptr()).parent = Some(node_a);
                }
                (*node_a.as_ptr()).is_red = false;
                (*node_b.as_ptr()).right = Some(node_a);
                (*node_a.as_ptr()).parent = Some(node_b);
                (*node_b.as_ptr()).is_red = true;
                if let Some(node_c) = (*node_b.as_ptr()).left {
                    (*node_c.as_ptr()).is_red = false;
                }
            }
        }

        /// 2.1.1.2 remove black X
        ///
        /// ```text
        ///             P              P
        ///            //             //
        ///           A               C
        ///          / \            /   \
        ///         X   B   =>     A     B
        ///            //           \   /
        ///            C             E D
        ///           / \
        ///          E   D
        /// ```
        unsafe fn remove_black_leaf_2_1_1_2_balancing(&mut self, node_x: &NonNull<Node<T>>) {
            unsafe {
                let node_a = (*node_x.as_ptr()).parent.unwrap();
                (*node_a.as_ptr()).is_red = false;
                let parent: NonNull<Node<T>> = (*node_a.as_ptr()).parent.unwrap();
                let node_b = (*node_a.as_ptr()).right.unwrap();
                let node_c = (*node_b.as_ptr()).left.unwrap();
                let node_e = (*node_c.as_ptr()).left;
                let node_d = (*node_c.as_ptr()).right;
                (*parent.as_ptr()).left = Some(node_c);
                (*node_c.as_ptr()).parent = Some(parent);
                (*node_b.as_ptr()).left = node_d;
                if let Some(n_d) = node_d {
                    (*n_d.as_ptr()).parent = Some(node_b);
                }
                (*node_c.as_ptr()).right = Some(node_b);
                (*node_b.as_ptr()).parent = Some(node_c);
                (*node_c.as_ptr()).left = Some(node_a);
                (*node_a.as_ptr()).parent = Some(node_c);
                (*node_a.as_ptr()).right = node_e;
                if let Some(n_e) = node_e {
                    (*n_e.as_ptr()).parent = Some(node_a);
                }
            }
        }

        /// 2.1.2.1 remove black X
        ///
        /// ```text
        ///              P            P
        ///             //           /
        ///            A            A
        ///           / \          //
        ///          B   X   =>   B
        ///
        /// ```
        unsafe fn remove_black_leaf_2_1_2_1_balancing(&mut self, node_x: &NonNull<Node<T>>) {
            unsafe {
                let node_a = (*node_x.as_ptr()).parent.unwrap();
                (*node_a.as_ptr()).is_red = false;
                if let Some(node_b) = (*node_a.as_ptr()).left {
                    (*node_b.as_ptr()).is_red = true;
                }
            }
        }

        /// 2.1.2.2 remove black X
        ///
        /// ```text
        ///             P            P
        ///            //           /
        ///            A     =>     B
        ///           / \          //\
        ///          X   B        A   D
        ///             / \        \
        ///            C   D        C
        /// ```
        unsafe fn remove_black_leaf_2_1_2_2_balancing(&mut self, node_x: &NonNull<Node<T>>) {
            unsafe {
                let node_a = (*node_x.as_ptr()).parent.unwrap();
                let node_b = (*node_a.as_ptr()).right.unwrap();
                let node_c = (*node_b.as_ptr()).left;
                let node_d = (*node_b.as_ptr()).right;
                let parent = (*node_a.as_ptr()).parent.unwrap();
                if let Some(left) = (*parent.as_ptr()).left {
                    if std::ptr::eq(node_a.as_ptr(), left.as_ptr()) {
                        (*parent.as_ptr()).left = Some(node_b);
                    } else {
                        (*parent.as_ptr()).right = Some(node_b);
                    }
                } else {
                    (*parent.as_ptr()).right = Some(node_b);
                }
                (*node_b.as_ptr()).parent = Some(parent);
                (*node_b.as_ptr()).left = Some(node_a);
                (*node_b.as_ptr()).right = node_d;
                if let Some(n_d) = node_d {
                    (*n_d.as_ptr()).parent = Some(node_b);
                }
                (*node_a.as_ptr()).parent = Some(node_b);
                (*node_a.as_ptr()).right = node_c;
                if let Some(n_c) = node_c {
                    (*n_c.as_ptr()).parent = Some(node_a);
                }
            }
        }

        /// 2.2.1 remove black X
        ///
        /// ```text
        ///            A               C
        ///          // \            //  \
        ///         B    X    =>    B     A
        ///          \               \   /
        ///           C               D E
        ///           //\
        ///          D   E
        /// ```
        unsafe fn remove_black_leaf_2_2_1_balancing(&mut self, node_x: &NonNull<Node<T>>) {
            unsafe {
                let n_a = node_x.as_ref().parent.unwrap();
                if n_a.as_ref().parent.is_some() {
                    let parent = (*n_a.as_ptr()).parent.unwrap();
                    let mut node_a_from_left = false;
                    if let Some(ref mut node_a) = (*parent.as_ptr()).left
                        && std::ptr::eq(node_a.as_ptr(), n_a.as_ptr())
                    {
                        node_a_from_left = true;
                    }
                    let node_a = if node_a_from_left {
                        (*parent.as_ptr()).left.unwrap()
                    } else {
                        (*parent.as_ptr()).right.unwrap()
                    };
                    let node_b = (*node_a.as_ptr()).left.unwrap();
                    let node_c = (*node_b.as_ptr()).right.unwrap();
                    let node_e = (*node_c.as_ptr()).right;
                    let node_d = (*node_c.as_ptr()).left.unwrap();
                    (*node_b.as_ptr()).right = Some(node_d);
                    (*node_b.as_ptr()).parent = Some(node_c);
                    (*node_d.as_ptr()).parent = Some(node_b);
                    (*node_a.as_ptr()).parent = Some(node_c);
                    (*node_a.as_ptr()).left = node_e;
                    if let Some(n_e) = node_e {
                        (*n_e.as_ptr()).parent = Some(node_a);
                    }
                    (*node_d.as_ptr()).is_red = false;
                    (*node_c.as_ptr()).left = Some(node_b);
                    (*node_c.as_ptr()).right = Some(node_a);
                    (*node_c.as_ptr()).parent = Some(parent);
                    if node_a_from_left {
                        (*parent.as_ptr()).left = Some(node_c);
                    } else {
                        (*parent.as_ptr()).right = Some(node_c);
                    }
                } else {
                    // node_a is root
                    if let Some(fixed_head) = self.fixed_head {
                        let node_a = (*fixed_head.as_ptr()).left.unwrap();
                        let node_b = (*node_a.as_ptr()).left.unwrap();
                        let node_c = (*node_b.as_ptr()).right.unwrap();
                        let node_e = (*node_c.as_ptr()).right;
                        let node_d = (*node_c.as_ptr()).left.unwrap();
                        (*node_b.as_ptr()).right = Some(node_d);
                        (*node_b.as_ptr()).parent = Some(node_c);
                        (*node_d.as_ptr()).parent = Some(node_b);
                        (*node_a.as_ptr()).parent = Some(node_c);
                        (*node_a.as_ptr()).left = node_e;
                        if let Some(n_e) = node_e {
                            (*n_e.as_ptr()).parent = Some(node_a);
                        }
                        (*node_d.as_ptr()).is_red = false;
                        (*node_c.as_ptr()).left = Some(node_b);
                        (*node_c.as_ptr()).right = Some(node_a);
                        (*node_c.as_ptr()).parent = None;
                        (*fixed_head.as_ptr()).left = Some(node_c);
                    }
                }
            }
        }

        /// 2.2.2 remove black X
        ///
        /// ```text
        ///    A            B
        ///  // \            \
        ///  B    X   =>       A
        ///  \               //
        ///   C             C
        /// ```
        unsafe fn remove_black_leaf_2_2_2_balancing(&mut self, node_x: &NonNull<Node<T>>) {
            unsafe {
                let n_a = node_x.as_ref().parent.unwrap();
                if n_a.as_ref().parent.is_some() {
                    let parent = (*n_a.as_ptr()).parent.unwrap();
                    let mut node_a_from_left = false;
                    if let Some(ref mut node_a) = (*parent.as_ptr()).left
                        && std::ptr::eq(node_a.as_ptr(), n_a.as_ptr())
                    {
                        node_a_from_left = true;
                    }
                    let node_a = if node_a_from_left {
                        (*parent.as_ptr()).left.unwrap()
                    } else {
                        (*parent.as_ptr()).right.unwrap()
                    };
                    let node_b = (*node_a.as_ptr()).left.unwrap();
                    (*node_b.as_ptr()).is_red = false;
                    (*node_b.as_ptr()).parent = Some(parent);
                    let node_c = (*node_b.as_ptr()).right.unwrap();
                    (*node_c.as_ptr()).is_red = true;
                    (*node_b.as_ptr()).right = Some(node_a);
                    (*node_a.as_ptr()).left = Some(node_c);
                    (*node_c.as_ptr()).parent = Some(node_a);
                    (*node_a.as_ptr()).parent = Some(node_b);
                    if node_a_from_left {
                        (*parent.as_ptr()).left = Some(node_b);
                    } else {
                        (*parent.as_ptr()).right = Some(node_b);
                    }
                } else {
                    // node_a is root
                    if let Some(fixed_head) = self.fixed_head {
                        let node_a = (*fixed_head.as_ptr()).left.unwrap();
                        let node_b = (*node_a.as_ptr()).left.unwrap();
                        (*node_b.as_ptr()).is_red = false;
                        (*node_b.as_ptr()).parent = None;
                        let node_c = (*node_b.as_ptr()).right.unwrap();
                        (*node_c.as_ptr()).is_red = true;
                        (*node_b.as_ptr()).right = Some(node_a);
                        (*node_a.as_ptr()).left = Some(node_c);
                        (*node_c.as_ptr()).parent = Some(node_a);
                        (*node_a.as_ptr()).parent = Some(node_b);
                        (*fixed_head.as_ptr()).left = Some(node_b);
                    }
                }
            }
        }

        /// 2.3.1.1 remove black X
        ///
        /// ```text
        ///      A           B
        ///     / \         / \
        ///    B   X  =>   D   A
        ///   // \            /
        ///  D    C          C
        /// ```
        unsafe fn remove_black_leaf_2_3_1_1_balancing(&mut self, node_x: &NonNull<Node<T>>) {
            unsafe {
                let node_a = (*node_x.as_ptr()).parent.unwrap();
                if let Some(parent) = (*node_a.as_ptr()).parent {
                    let node_b = (*node_a.as_ptr()).left.unwrap();
                    let node_c = (*node_b.as_ptr()).right;
                    let node_d = (*node_b.as_ptr()).left.unwrap();
                    (*node_d.as_ptr()).is_red = false;
                    let mut node_a_from_left = false;
                    if let Some(p_node_a) = (*parent.as_ptr()).left
                        && std::ptr::eq(p_node_a.as_ptr(), node_a.as_ptr())
                    {
                        node_a_from_left = true;
                    }
                    (*node_b.as_ptr()).parent = Some(parent);
                    (*node_b.as_ptr()).right = Some(node_a);
                    (*node_a.as_ptr()).parent = Some(node_b);
                    (*node_a.as_ptr()).left = node_c;
                    if let Some(n_c) = node_c {
                        (*n_c.as_ptr()).parent = Some(node_a);
                    }
                    if node_a_from_left {
                        (*parent.as_ptr()).left = Some(node_b);
                    } else {
                        (*parent.as_ptr()).right = Some(node_b);
                    }
                } else {
                    // node_a is root
                    if let Some(fixed_head) = self.fixed_head {
                        let node_a = (*fixed_head.as_ptr()).left.unwrap();
                        let node_b = (*node_a.as_ptr()).left.unwrap();
                        let node_c = (*node_b.as_ptr()).right;
                        let node_d = (*node_b.as_ptr()).left.unwrap();
                        (*node_d.as_ptr()).is_red = false;
                        let node_b = (*node_a.as_ptr()).left.unwrap();
                        (*node_b.as_ptr()).parent = None;
                        (*node_b.as_ptr()).right = Some(node_a);
                        (*node_a.as_ptr()).parent = Some(node_b);
                        (*node_a.as_ptr()).left = node_c;
                        if let Some(n_c) = node_c {
                            (*n_c.as_ptr()).parent = Some(node_a);
                        }
                        (*fixed_head.as_ptr()).left = Some(node_b);
                    }
                }
            }
        }

        /// 2.3.1.2 remove black X
        ///
        /// ```text
        ///
        ///      A            D
        ///     / \         /   \
        ///    X   B  =>   A     B
        ///       //        \   /
        ///       D          C E
        ///      / \
        ///     C   E
        /// ```
        unsafe fn remove_black_leaf_2_3_1_2_balancing(&mut self, node_x: &NonNull<Node<T>>) {
            unsafe {
                let node_a = (*node_x.as_ptr()).parent.unwrap();
                if let Some(parent) = (*node_a.as_ptr()).parent {
                    let node_b = (*node_a.as_ptr()).right.unwrap();
                    let node_d = (*node_b.as_ptr()).left.unwrap();
                    let node_c = (*node_d.as_ptr()).left;
                    let node_e = (*node_d.as_ptr()).right;
                    (*node_d.as_ptr()).is_red = false;
                    let mut node_a_from_left = false;
                    if let Some(p_node_a) = (*parent.as_ptr()).left
                        && std::ptr::eq(p_node_a.as_ptr(), node_a.as_ptr())
                    {
                        node_a_from_left = true;
                    }
                    (*node_d.as_ptr()).parent = Some(parent);
                    (*node_d.as_ptr()).left = Some(node_a);
                    (*node_d.as_ptr()).right = Some(node_b);
                    (*node_a.as_ptr()).parent = Some(node_d);
                    (*node_b.as_ptr()).parent = Some(node_d);
                    (*node_a.as_ptr()).right = node_c;
                    if let Some(n_c) = node_c {
                        (*n_c.as_ptr()).parent = Some(node_a);
                    }
                    (*node_b.as_ptr()).left = node_e;
                    if let Some(n_e) = node_e {
                        (*n_e.as_ptr()).parent = Some(node_b);
                    }
                    if node_a_from_left {
                        (*parent.as_ptr()).left = Some(node_d);
                    } else {
                        (*parent.as_ptr()).right = Some(node_d);
                    }
                } else {
                    // node_a is root
                    if let Some(fixed_head) = self.fixed_head {
                        let node_a = (*fixed_head.as_ptr()).left.unwrap();
                        let node_b = (*node_a.as_ptr()).right.unwrap();
                        let node_d = (*node_b.as_ptr()).left.unwrap();
                        let node_c = (*node_d.as_ptr()).left;
                        let node_e = (*node_d.as_ptr()).right;
                        (*node_d.as_ptr()).is_red = false;
                        (*node_d.as_ptr()).parent = None;
                        (*node_d.as_ptr()).left = Some(node_a);
                        (*node_d.as_ptr()).right = Some(node_b);
                        (*node_a.as_ptr()).parent = Some(node_d);
                        (*node_b.as_ptr()).parent = Some(node_d);
                        (*node_a.as_ptr()).right = node_c;
                        if let Some(n_c) = node_c {
                            (*n_c.as_ptr()).parent = Some(node_a);
                        }
                        (*node_b.as_ptr()).left = node_e;
                        if let Some(n_e) = node_e {
                            (*n_e.as_ptr()).parent = Some(node_b);
                        }
                        (*fixed_head.as_ptr()).left = Some(node_d);
                    }
                }
            }
        }

        /// 2.3.2.1 remove black X
        ///
        /// ```text
        ///            P           P
        ///            |           |
        ///            A           A
        ///           / \   =>    //   => next check node A
        ///          B   X       B
        ///
        /// ```
        unsafe fn remove_black_leaf_2_3_2_1_balancing(
            &mut self,
            node_x: &NonNull<Node<T>>,
        ) -> NonNull<Node<T>> {
            unsafe {
                let node_a = (*node_x.as_ptr()).parent.unwrap();
                let node_b = (*node_a.as_ptr()).left.unwrap();
                (*node_b.as_ptr()).is_red = true;
                node_a
            }
        }

        /// 2.3.2.2 remove black X
        ///
        /// ```text
        ///              A            B
        ///             / \   =>    // \    =>  next check node B
        ///            X   B       A    D
        ///               / \       \
        ///              C   D       C
        /// ```
        unsafe fn remove_black_leaf_2_3_2_2_balancing(
            &mut self,
            node_x: &NonNull<Node<T>>,
        ) -> NonNull<Node<T>> {
            unsafe {
                let node_a = (*node_x.as_ptr()).parent.unwrap();
                (*node_a.as_ptr()).is_red = true;
                if let Some(parent) = (*node_a.as_ptr()).parent {
                    let node_b = (*node_a.as_ptr()).right.unwrap();
                    let node_c = (*node_b.as_ptr()).left;
                    let node_d = (*node_b.as_ptr()).right;
                    let mut node_a_from_left = false;
                    if let Some(p_node_a) = (*parent.as_ptr()).left
                        && std::ptr::eq(p_node_a.as_ptr(), node_a.as_ptr())
                    {
                        node_a_from_left = true;
                    }
                    (*node_b.as_ptr()).parent = Some(parent);
                    (*node_a.as_ptr()).right = node_c;
                    if let Some(n_c) = node_c {
                        (*n_c.as_ptr()).parent = Some(node_a);
                    }
                    (*node_b.as_ptr()).right = node_d;
                    if let Some(n_d) = node_d {
                        (*n_d.as_ptr()).parent = Some(node_b);
                    }
                    (*node_b.as_ptr()).left = Some(node_a);
                    (*node_a.as_ptr()).parent = Some(node_b);
                    if node_a_from_left {
                        (*parent.as_ptr()).left = Some(node_b);
                    } else {
                        (*parent.as_ptr()).right = Some(node_b);
                    }
                    node_b
                } else {
                    // node_a is root
                    if let Some(fixed_head) = self.fixed_head {
                        let node_a = (*fixed_head.as_ptr()).left.unwrap();
                        (*node_a.as_ptr()).is_red = true;
                        let node_b = (*node_a.as_ptr()).right.unwrap();
                        let node_c = (*node_b.as_ptr()).left;
                        let node_d = (*node_b.as_ptr()).right;
                        (*node_b.as_ptr()).parent = None;
                        (*node_a.as_ptr()).right = node_c;
                        if let Some(n_c) = node_c {
                            (*n_c.as_ptr()).parent = Some(node_a);
                        }
                        (*node_b.as_ptr()).right = node_d;
                        if let Some(n_d) = node_d {
                            (*n_d.as_ptr()).parent = Some(node_b);
                        }
                        (*node_b.as_ptr()).left = Some(node_a);
                        (*node_a.as_ptr()).parent = Some(node_b);
                        (*fixed_head.as_ptr()).left = Some(node_b);
                    }
                    self.get_root().unwrap()
                }
            }
        }

        unsafe fn remove_node(&mut self, node: NonNull<Node<T>>) -> bool {
            unsafe {
                match self.operation_remove(&node) {
                    OperationRemove::RedLeaf => {
                        // option 1.0.0
                        //
                        // ```text
                        //
                        //  P
                        //  ||
                        //  X
                        //
                        // ```

                        self.remove_leaf(node)
                    }
                    OperationRemove::BlackLeaf => {
                        // option 2 black leaf
                        self.remove_black_leaf(node)
                    }
                    OperationRemove::NodeWithChildren => {
                        // option 4.0.0
                        // ```text
                        //        X
                        //     /      \
                        //    L        R
                        //   / \      / \
                        // ...  C    L
                        //          /
                        //         C
                        //        ...
                        //
                        // ```
                        /*
                            The node has two children.

                            We take the predecessor:
                            the maximal node of the left subtree.

                            We only change the values,
                            then we delete the predecessor as a regular node.
                        */

                        let predecessor = self.find_max(node.as_ref().left.unwrap());

                        std::mem::swap(
                            &mut (*node.as_ptr()).value,
                            &mut (*predecessor.as_ptr()).value,
                        );

                        self.remove_node(predecessor)
                    }
                    OperationRemove::BlackNodeWithRedLeaf => {
                        // option 3.0.0
                        // ```text
                        //  X
                        // //
                        // A
                        // ```
                        let red_left = (*node.as_ptr()).left.unwrap();
                        std::mem::swap(&mut (*node.as_ptr()).value, &mut (*red_left.as_ptr()).value);
                        self.remove_leaf(red_left)
                    }
                }
            }
        }

        unsafe fn find_max(&self, node: NonNull<Node<T>>) -> NonNull<Node<T>> {
            unsafe {
                if node.as_ref().right.is_some() {
                    self.find_max(node.as_ref().right.unwrap())
                } else {
                    node
                }
            }
        }

        unsafe fn find_min(&self, node: NonNull<Node<T>>) -> NonNull<Node<T>> {
            unsafe {
                if node.as_ref().left.is_some() {
                    self.find_min(node.as_ref().left.unwrap())
                } else {
                    node
                }
            }
        }

        unsafe fn remove_leaf(&mut self, node: NonNull<Node<T>>) -> bool {
            unsafe {
                if let Some(mut parent) = node.as_ref().parent {
                    if let Some(ref mut left) = parent.as_mut().left {
                        if std::ptr::eq(left.as_ptr(), node.as_ptr()) {
                            parent.as_mut().left = None;
                        } else {
                            parent.as_mut().right = None;
                        }
                    } else {
                        parent.as_mut().right = None;
                    }
                }
                let _ = Box::from_raw(node.as_ptr());
                true
            }
        }

        unsafe fn remove_tree(&mut self, node: Link<T>) {
            unsafe {
                if let Some(node) = node {
                    self.remove_tree(node.as_ref().left);
                    self.remove_tree(node.as_ref().right);
                    if self.remove_leaf(node) {
                        assert!(self.count > 0);
                        self.count -= 1;
                    }
                }
            }
        }

        /// Rotate left and Rotate right and Flip color
        ///
        /// ```text
        ///             |              ||
        ///             P              C
        ///           //  \          /   \
        ///          A     F        A     P
        ///         / \\      =>   / \   / \
        ///        B   C          B   E D   F
        ///            / \
        ///           E   D
        /// ```
        unsafe fn rotate_left_right_flip_color(&mut self, node_a: NonNull<Node<T>>) -> Link<T> {
            unsafe {
                let node_p = (*node_a.as_ptr()).parent.unwrap();
                if let Some(parent) = (*node_p.as_ptr()).parent {
                    let mut node_p_from_left = false;
                    if let Some(p_node_p) = (*parent.as_ptr()).left
                        && std::ptr::eq(p_node_p.as_ptr(), node_p.as_ptr())
                    {
                        node_p_from_left = true;
                    }
                    let node_p = if node_p_from_left {
                        (*parent.as_ptr()).left.unwrap()
                    } else {
                        (*parent.as_ptr()).right.unwrap()
                    };
                    (*node_a.as_ptr()).is_red = false;
                    let node_c = (*node_a.as_ptr()).right.unwrap();
                    (*node_c.as_ptr()).is_red = false;
                    let node_e = (*node_c.as_ptr()).left;
                    let node_d = (*node_c.as_ptr()).right;
                    (*node_c.as_ptr()).is_red = true;
                    (*node_c.as_ptr()).parent = Some(parent);
                    (*node_c.as_ptr()).left = Some(node_a);
                    (*node_a.as_ptr()).parent = Some(node_c);
                    (*node_c.as_ptr()).right = Some(node_p);
                    (*node_p.as_ptr()).parent = Some(node_c);
                    (*node_p.as_ptr()).left = node_d;
                    if let Some(n_d) = node_d {
                        (*n_d.as_ptr()).parent = Some(node_p);
                    }
                    (*node_a.as_ptr()).right = node_e;
                    if let Some(n_e) = node_e {
                        (*n_e.as_ptr()).parent = Some(node_a);
                    }
                    if node_p_from_left {
                        (*parent.as_ptr()).left = Some(node_c);
                    } else {
                        (*parent.as_ptr()).right = Some(node_c);
                    }
                    Some(parent)
                } else {
                    let fixed_head = self.fixed_head.unwrap();
                    let node_p = (*fixed_head.as_ptr()).left.unwrap();

                    let node_a = (*node_p.as_ptr()).left.unwrap();
                    (*node_a.as_ptr()).is_red = false;
                    let node_c = (*node_a.as_ptr()).right.unwrap();
                    (*node_c.as_ptr()).is_red = false;
                    let node_e = (*node_c.as_ptr()).left;
                    let node_d = (*node_c.as_ptr()).right;
                    (*node_c.as_ptr()).is_red = false;
                    (*node_c.as_ptr()).parent = None;
                    (*node_c.as_ptr()).left = Some(node_a);
                    (*node_a.as_ptr()).parent = Some(node_c);
                    (*node_c.as_ptr()).right = Some(node_p);
                    (*node_p.as_ptr()).parent = Some(node_c);
                    (*node_p.as_ptr()).left = node_d;
                    if let Some(n_d) = node_d {
                        (*n_d.as_ptr()).parent = Some(node_p);
                    }
                    (*node_a.as_ptr()).right = node_e;
                    if let Some(n_e) = node_e {
                        (*n_e.as_ptr()).parent = Some(node_a);
                    }
                    (*fixed_head.as_ptr()).left = Some(node_c);
                    (*fixed_head.as_ptr()).left
                }
            }
        }

        /// Rotate left without parent
        /// A is root
        ///
        /// ```text
        ///             A                  C
        ///            / \\               //\
        ///           B    C     =>      A   D
        ///               / \           / \
        ///              E   D         B   E
        ///
        /// ```
        ///
        /// Rotate left  with parent
        ///
        /// ```text
        ///             P                  P
        ///             |                  |
        ///             A                  C
        ///            / \\               //\
        ///           B    C     =>      A   D
        ///               / \           / \
        ///              E   D         B   E
        ///
        /// ```
        unsafe fn rotate_left(&mut self, node_a: NonNull<Node<T>>) -> Link<T> {
            unsafe {
                if let Some(parent) = (*node_a.as_ptr()).parent {
                    let mut node_a_from_left = false;
                    if let Some(p_node_a) = (*parent.as_ptr()).left
                        && std::ptr::eq(p_node_a.as_ptr(), node_a.as_ptr())
                    {
                        node_a_from_left = true;
                    }
                    let node_a = if node_a_from_left {
                        (*parent.as_ptr()).left.unwrap()
                    } else {
                        (*parent.as_ptr()).right.unwrap()
                    };
                    let node_c = (*node_a.as_ptr()).right.unwrap();
                    (*node_c.as_ptr()).is_red = (*node_a.as_ptr()).is_red;
                    (*node_a.as_ptr()).is_red = true;
                    (*node_c.as_ptr()).parent = Some(parent);
                    if node_c.as_ref().left.is_some() {
                        let mut node_e = (*node_c.as_ptr()).left;
                        if let Some(e) = &mut node_e {
                            (*e.as_ptr()).parent = Some(node_a);
                        }
                        (*node_a.as_ptr()).right = node_e;
                    } else {
                        (*node_a.as_ptr()).right = None;
                    }
                    (*node_c.as_ptr()).left = Some(node_a);
                    (*node_a.as_ptr()).parent = Some(node_c);
                    if node_a_from_left {
                        (*parent.as_ptr()).left = Some(node_c);
                        (*parent.as_ptr()).left
                    } else {
                        (*parent.as_ptr()).right = Some(node_c);
                        (*parent.as_ptr()).right
                    }
                } else {
                    let fixed_head = self.fixed_head.unwrap();
                    let node_a = (*fixed_head.as_ptr()).left.unwrap();
                    let node_c = (*node_a.as_ptr()).right.unwrap();
                    (*node_c.as_ptr()).is_red = (*node_a.as_ptr()).is_red;
                    (*node_a.as_ptr()).is_red = true;
                    if node_c.as_ref().left.is_some() {
                        let mut node_e = (*node_c.as_ptr()).left;
                        if let Some(e) = &mut node_e {
                            (*e.as_ptr()).parent = Some(node_a);
                        }
                        (*node_a.as_ptr()).right = node_e;
                    } else {
                        (*node_a.as_ptr()).right = None;
                    }
                    (*node_c.as_ptr()).left = Some(node_a);
                    (*node_a.as_ptr()).parent = Some(node_c);
                    (*node_c.as_ptr()).parent = None;
                    (*fixed_head.as_ptr()).left = Some(node_c);
                    (*fixed_head.as_ptr()).left
                }
            }
        }

        /// Rotate right without parent
        /// A is root
        ///
        /// ```text
        ///              A               B
        ///            // \             / \\
        ///            B   C     =>    E    A
        ///          // \                  / \
        ///         E    D                D   C
        /// ```
        ///
        /// Rotate right with parent
        ///
        /// ```text
        ///                P               P
        ///                |               |
        ///                A               B
        ///              // \             / \\
        ///              B   C     =>    E    A
        ///            // \                  / \
        ///           E    D                D   C
        ///
        /// ```
        unsafe fn rotate_right(&mut self, node_a: NonNull<Node<T>>) -> Link<T> {
            unsafe {
                if let Some(parent) = (*node_a.as_ptr()).parent {
                    let mut node_a_from_left = false;
                    if let Some(p_node_a) = (*parent.as_ptr()).left
                        && std::ptr::eq(p_node_a.as_ptr(), node_a.as_ptr())
                    {
                        node_a_from_left = true;
                    }
                    let node_a = if node_a_from_left {
                        (*parent.as_ptr()).left.unwrap()
                    } else {
                        (*parent.as_ptr()).right.unwrap()
                    };
                    let node_b = (*node_a.as_ptr()).left.unwrap();
                    (*node_b.as_ptr()).parent = Some(parent);
                    (*node_b.as_ptr()).is_red = (*node_a.as_ptr()).is_red;
                    (*node_a.as_ptr()).is_red = true;
                    if node_b.as_ref().right.is_some() {
                        let mut node_d = (*node_b.as_ptr()).right;
                        if let Some(d) = &mut node_d {
                            (*d.as_ptr()).parent = Some(node_a);
                        }
                        (*node_a.as_ptr()).left = node_d;
                    } else {
                        (*node_a.as_ptr()).left = None;
                    }
                    (*node_b.as_ptr()).right = Some(node_a);
                    (*node_a.as_ptr()).parent = Some(node_b);
                    if node_a_from_left {
                        (*parent.as_ptr()).left = Some(node_b);
                        (*parent.as_ptr()).left
                    } else {
                        (*parent.as_ptr()).right = Some(node_b);
                        (*parent.as_ptr()).right
                    }
                } else {
                    let fixed_head = self.fixed_head.unwrap();
                    let node_a = (*fixed_head.as_ptr()).left.unwrap();
                    let node_b = (*node_a.as_ptr()).left.unwrap();
                    (*node_b.as_ptr()).is_red = (*node_a.as_ptr()).is_red;
                    (*node_a.as_ptr()).is_red = true;
                    if node_b.as_ref().right.is_some() {
                        let mut node_d = (*node_b.as_ptr()).right;
                        if let Some(d) = &mut node_d {
                            (*d.as_ptr()).parent = Some(node_a);
                        }
                        (*node_a.as_ptr()).left = node_d;
                    } else {
                        (*node_a.as_ptr()).left = None;
                    }
                    (*node_b.as_ptr()).right = Some(node_a);
                    (*node_a.as_ptr()).parent = Some(node_b);
                    (*node_b.as_ptr()).parent = None;
                    (*fixed_head.as_ptr()).left = Some(node_b);
                    (*fixed_head.as_ptr()).left
                }
            }
        }

        /// Flip color
        ///
        /// ```text
        ///             |          ||
        ///             A    =>    A
        ///           // \\       / \
        ///          B    C      B   C
        ///
        /// ```
        unsafe fn flip_colors(&mut self, mut node: NonNull<Node<T>>) {
            unsafe {
                if node.as_ref().left.is_some() && node.as_ref().right.is_some() {
                    if let Some(ref mut left) = node.as_mut().left {
                        left.as_mut().is_red = false;
                    }
                    if let Some(ref mut right) = node.as_mut().right {
                        right.as_mut().is_red = false;
                    }
                    node.as_mut().is_red = true;

                    if (*node.as_ptr()).parent.is_none() {
                        node.as_mut().is_red = false;
                    }
                }
            }
        }

        unsafe fn check_put_balancing(&mut self, node: NonNull<Node<T>>) -> OperationPut {
            unsafe {
                if node.as_ref().right.is_some() {
                    let r = node.as_ref().right.unwrap();
                    if node.as_ref().left.is_some() && !node.as_ref().is_red {
                        let l = node.as_ref().left.unwrap();
                        if l.as_ref().is_red && r.as_ref().is_red {
                            return OperationPut::FlipColors;
                        }
                    }
                    if r.as_ref().is_red {
                        return OperationPut::Left;
                    }
                }
                if node.as_ref().is_red && node.as_ref().left.is_some() {
                    let l = node.as_ref().left.unwrap();
                    if l.as_ref().is_red {
                        return OperationPut::Right;
                    }
                }
                OperationPut::Nothing
            }
        }

        unsafe fn put_balancing(&mut self, next: NonNull<Node<T>>) {
            unsafe {
                let mut next = next;
                loop {
                    match self.check_put_balancing(next) {
                        OperationPut::Left => {
                            if (*next.as_ptr()).is_red {
                                if let Some(n) = self.rotate_left_right_flip_color(next) {
                                    next = n;
                                }
                            } else {
                                if let Some(n) = self.rotate_left(next) {
                                    next = n;
                                }
                            }
                        }
                        OperationPut::Right => {
                            if (*next.as_ptr()).parent.is_some() {
                                let node_a = (*next.as_ptr()).parent.unwrap();
                                if let Some(n) = self.rotate_right(node_a) {
                                    next = n;
                                }
                            }
                        }
                        OperationPut::FlipColors => {
                            self.flip_colors(next);
                            if (*next.as_ptr()).parent.is_some() {
                                next = (*next.as_ptr()).parent.unwrap();
                            } else {
                                break;
                            }
                        }
                        OperationPut::Nothing => {
                            break;
                        }
                    }
                }
            }
        }

        unsafe fn find_put_parent_candidate(&mut self, parent: Link<T>, elem: &T) -> Link<T> {
            unsafe {
                if let Some(parent) = parent {
                    match elem.cmp(&parent.as_ref().value) {
                        Ordering::Equal => None,
                        Ordering::Less => {
                            if (*parent.as_ptr()).left.is_some() {
                                self.find_put_parent_candidate((*parent.as_ptr()).left, elem)
                            } else {
                                Some(parent)
                            }
                        }
                        Ordering::Greater => {
                            if (*parent.as_ptr()).right.is_some() {
                                self.find_put_parent_candidate((*parent.as_ptr()).right, elem)
                            } else {
                                Some(parent)
                            }
                        }
                    }
                } else {
                    parent
                }
            }
        }

        unsafe fn attach_node(&mut self, parent: NonNull<Node<T>>, elem: T) -> bool {
            unsafe {
                match elem.cmp(&parent.as_ref().value) {
                    Ordering::Equal => false,
                    Ordering::Less => {
                        (*parent.as_ptr()).left = Node::new_red(elem, parent);
                        true
                    }
                    Ordering::Greater => {
                        (*parent.as_ptr()).right = Node::new_red(elem, parent);
                        true
                    }
                }
            }
        }

        /// Returns the default iterator over the tree.
        ///
        /// The default traversal is in-order (`LNR`), so values are yielded in
        /// ascending order.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([3, 1, 2]);
        ///
        /// let values: Vec<i32> = tree.iter().copied().collect();
        ///
        /// assert_eq!(values, vec![1, 2, 3]);
        /// ```
        pub fn iter(&self) -> IterInOrder<'_, T> {
            self.iter_inorder()
        }

        /// Returns an in-order (`LNR`) iterator.
        ///
        /// Values are yielded in ascending order.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([3, 1, 2]);
        ///
        /// assert_eq!(
        ///     tree.iter_inorder().copied().collect::<Vec<_>>(),
        ///     vec![1, 2, 3]
        /// );
        /// ```
        pub fn iter_inorder(&self) -> IterInOrder<'_, T> {
            unsafe { IterInOrder::new(leftmost_child_in_order(self.get_root()), self.count) }
        }

        /// Returns a reverse in-order (`RNL`) iterator.
        ///
        /// Values are yielded in descending order.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([3, 1, 2]);
        ///
        /// assert_eq!(
        ///     tree.iter_reverse_inorder().copied().collect::<Vec<_>>(),
        ///     vec![3, 2, 1]
        /// );
        /// ```
        pub fn iter_reverse_inorder(&self) -> IterReverseInOrder<'_, T> {
            unsafe {
                IterReverseInOrder::new(
                    rightmost_child_reverse_in_order(self.get_root()),
                    self.count,
                )
            }
        }

        /// Returns a pre-order (`NLR`) iterator.
        ///
        /// The current node is visited before its left and right subtrees.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([4, 2, 6, 1, 3, 5, 7]);
        ///
        /// let values: Vec<i32> = tree.iter_preorder().copied().collect();
        ///
        /// assert_eq!(values.len(), tree.len());
        /// ```
        pub fn iter_preorder(&self) -> IterPreOrder<'_, T> {
            IterPreOrder::new(self.get_root(), self.count)
        }

        /// Returns a post-order (`LRN`) iterator.
        ///
        /// The left and right subtrees are visited before the current node.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([4, 2, 6, 1, 3, 5, 7]);
        ///
        /// let values: Vec<i32> = tree.iter_postorder().copied().collect();
        ///
        /// assert_eq!(values.len(), tree.len());
        /// ```
        pub fn iter_postorder(&self) -> IterPostOrder<'_, T> {
            unsafe {
                let first = self.get_root().map(|root| leaf_post_order(root));
                IterPostOrder::new(first, self.count)
            }
        }

        /// Returns all values in level-order traversal.
        ///
        /// Nodes are visited level by level, starting from the root.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([4, 2, 6, 1, 3, 5, 7]);
        ///
        /// let values = tree.iter_level_order();
        ///
        /// assert_eq!(values.len(), tree.len());
        /// ```
        pub fn iter_level_order(&self) -> Vec<&T> {
            let mut ret: Vec<&T> = vec![];
            if let Some(root) = self.get_root() {
                iter_level_order_impl(root, &mut ret);
            }
            ret
        }
    }

    impl<'a, T: Ord + Default> std::iter::IntoIterator for &'a RedBlackTree<T> {
        type IntoIter = IterInOrder<'a, T>;
        type Item = &'a T;

        fn into_iter(self) -> Self::IntoIter {
            self.iter()
        }
    }

    impl<T: Ord + Default> Drop for RedBlackTree<T> {
        fn drop(&mut self) {
            unsafe {
                if let Some(fixed_head) = self.fixed_head {
                    self.remove_tree((*fixed_head.as_ptr()).left);
                    let _ = Box::from_raw(fixed_head.as_ptr());
                }
                self.fixed_head = None;
            }
        }
    }

    fn find_node<T: Ord>(fromnode: Link<T>, value: &T) -> Link<T> {
        unsafe {
            if let Some(fromnode) = fromnode {
                match value.cmp(&(*fromnode.as_ptr()).value) {
                    Ordering::Equal => Some(fromnode),
                    Ordering::Less => find_node((*fromnode.as_ptr()).left, value),
                    Ordering::Greater => find_node((*fromnode.as_ptr()).right, value),
                }
            } else {
                fromnode
            }
        }
    }

    fn helper_display_tree<T: Display>(node: NonNull<Node<T>>) -> String {
        unsafe {
            let mut s: String = "".into();
            let color = if (*node.as_ptr()).is_red {
                "[color=\"red\"]"
            } else {
                "[color=\"black\"]"
            };

            if let Some(left) = (*node.as_ptr()).left {
                s.push_str(&format!(
                    "\t{n1}->{n2} {color1}; {n1} {color1}; {n2} {color2};\n",
                    n1 = (*node.as_ptr()).value,
                    n2 = (*left.as_ptr()).value,
                    color1 = color,
                    color2 = if (*left.as_ptr()).is_red {
                        "[color=\"red\"]"
                    } else {
                        "[color=\"black\"]"
                    },
                ));
                s.push_str(&helper_display_tree(left));
            } else if (*node.as_ptr()).right.is_some() {
                s.push_str(&format!(
                    "\t{n1}->node_null_{n1} [color=\"grey\"]; {n1} {color1};\n",
                    n1 = (*node.as_ptr()).value,
                    color1 = color
                ));
                s.push_str(&format!(
                    "\tnode_null_{n1}[label=\"null\"]\n",
                    n1 = (*node.as_ptr()).value
                ));
            }

            if let Some(right) = (*node.as_ptr()).right {
                s.push_str(&format!(
                    "\t{n1}->{n2} {color1}; {n1} {color1}; {n2} {color2};\n",
                    n1 = (*node.as_ptr()).value,
                    n2 = (*right.as_ptr()).value,
                    color2 = if (*right.as_ptr()).is_red {
                        "[color=\"red\"]"
                    } else {
                        "[color=\"black\"]"
                    },
                    color1 = color
                ));
                s.push_str(&helper_display_tree(right));
            } else {
                s.push_str(&format!(
                    "\t{n1}->node_null_{n1} [color=\"grey\"]; {n1} {color1};\n",
                    n1 = (*node.as_ptr()).value,
                    color1 = color
                ));
                s.push_str(&format!(
                    "\tnode_null_{}[label=\"null\"]\n",
                    (*node.as_ptr()).value
                ));
            }
            s
        }
    }

    impl<T: Ord + Default> Default for RedBlackTree<T> {
        fn default() -> Self {
            Self::new()
        }
    }

    impl<T: Ord + Default + Clone> Clone for RedBlackTree<T> {
        fn clone(&self) -> Self {
            let mut new_list = Self::new();
            for value in self {
                new_list.insert(value.clone());
            }
            new_list
        }
    }

    impl<T: Ord + Default> Extend<T> for RedBlackTree<T> {
        fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
            for value in iter {
                self.insert(value);
            }
        }
    }

    impl<T: Ord + Default> FromIterator<T> for RedBlackTree<T> {
        fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
            let mut list = Self::new();
            list.extend(iter);
            list
        }
    }

    impl<T: Ord + Default + Debug> Debug for RedBlackTree<T> {
        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
            f.debug_list().entries(self).finish()
        }
    }

    impl<T: Ord + Default> PartialEq for RedBlackTree<T> {
        fn eq(&self, other: &Self) -> bool {
            self.len() == other.len() && self.iter_inorder().eq(other.iter_inorder())
        }
    }

    impl<T: Ord + Default> Eq for RedBlackTree<T> {}

    impl<T: Ord + Default> PartialOrd for RedBlackTree<T> {
        fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
            Some(self.cmp(other))
        }
    }

    impl<T: Ord + Default> Ord for RedBlackTree<T> {
        fn cmp(&self, other: &Self) -> Ordering {
            self.iter_inorder().cmp(other.iter_inorder())
        }
    }

    impl<T: Ord + Default + std::hash::Hash> std::hash::Hash for RedBlackTree<T> {
        fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
            self.len().hash(state);
            for item in self {
                item.hash(state);
            }
        }
    }
}

2. Упорядоченная map-структура (ordered map)

Хранить пары key -> value, но с сохранением порядка ключей.

Полезно, когда кроме поиска по ключу нужны:

  • min/max key
  • predecessor/successor
  • range

Хранение уникальных обьектов пользователей в отсортированном виде:

(отличие от ordered set в том, что мы считаем ключом и что храним в узле)

use std::cmp::Ordering;

#[derive(Debug, Default)]
struct User {
    id: u32,
    name: String,
}
// Два пользователя считаются одинаковыми, если у них одинаковый id.
impl PartialEq for User {
    fn eq(&self, other: &Self) -> bool {
        self.id == other.id
    }
}
impl Eq for User {}
// Сортировка тоже идёт только по id.
impl PartialOrd for User {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}
impl Ord for User {
    fn cmp(&self, other: &Self) -> Ordering {
        self.id.cmp(&other.id)
    }
}
fn main() {
    let mut users = RedBlackTree::new();
    // Добавляем пары: id -> имя пользователя.
    users.insert(User {
        id: 20,
        name: "Alice".into(),
    });
    users.insert(User {
        id: 10,
        name: "Bob".into(),
    });
    users.insert(User {
        id: 40,
        name: "Charlie".into(),
    });
    users.insert(User {
        id: 30,
        name: "David".into(),
    });
    println!("Пользователи в порядке id:");
    for user in users.iter() {
        println!("{} -> {}", user.id, user.name);
    }
    // Для поиска достаточно создать временный ключ.
    // Поле name в сравнении не участвует.
    let key = User {
        id: 30,
        name: String::new(),
    };
    if let Some(user) = users.get(&key) {
        println!("\nНайден пользователь:");
        println!("{} -> {}", user.id, user.name);
    }
    // Обновляем value для существующего ключа.
    users.replace(User {
        id: 30,
        name: "Daniel".into(),
    });
    println!("\nПосле обновления пользователя id=30:");
    for user in users.iter() {
        println!("{} -> {}", user.id, user.name);
    }
}














/// -------------------------------------------
/// Implementation RBT
/// -------------------------------------------


pub use tree::RedBlackTree;
pub use iter::{IterInOrder, Range};
pub use iter::IterPreOrder;
pub use iter::IterReverseInOrder;
pub use iter::IterPostOrder;
 
pub mod iter{
    use std::ptr::NonNull;

    use crate::node::{Link, Node};

    ///```text
    ///
    ///            4
    ///          /   \
    ///         2     9
    ///        / \   //\
    ///       1   3  7   10
    ///             / \
    ///            6   8
    ///```
    ///    Depth-First Search / Pre-order (NLR):     4, 2, 1, 3, 9, 7, 6, 8, 10
    ///    Depth-First Search / In-order (LNR):      1, 2, 3, 4, 6, 7, 8, 9, 10
    ///    Depth-First Search / Post-order (LRN):    1, 3, 2, 6, 8, 7, 10, 9, 4
    ///    Breadth-First Search / Level-order:       4, 2, 9, 1, 3, 7, 10, 6, 8 
    pub use dfs_in_order::{IterInOrder, Range};

    pub(crate) use dfs_in_order::{leftmost_child_in_order, successor_of_node_in_order};

    mod dfs_in_order {
        use super::{Link, Node, NonNull};
        use std::iter::FusedIterator;
        use std::marker::PhantomData;

        /// Returns the next node in an in-order (`LNR`) traversal.
        ///
        /// # Safety
        ///
        /// `node` must point to a live node that belongs to the current tree, and
        /// all parent/child links reachable from it must be valid.
        pub unsafe fn successor_of_node_in_order<T>(node: NonNull<Node<T>>) -> Link<T> {
            unsafe {
                if node.as_ref().right.is_some() {
                    // If a right subtree exists, the successor is its leftmost node.
                    leftmost_child_in_order(node.as_ref().right)
                } else {
                    // Otherwise, walk up through parent links until the current
                    // node is found in a left subtree.
                    parent_with_left(node)
                }
            }
        }

        /// Returns the leftmost node reachable from `node`.
        ///
        /// Returns `None` when `node` is `None`.
        ///
        /// # Safety
        ///
        /// Every pointer reachable through `left` links must refer to a live node.
        pub unsafe fn leftmost_child_in_order<T>(node: Link<T>) -> Link<T> {
            unsafe {
                if let Some(node) = node {
                    if node.as_ref().left.is_none() {
                        Some(node)
                    } else {
                        leftmost_child_in_order(node.as_ref().left)
                    }
                } else {
                    node
                }
            }
        }

        /// Walks up the parent chain until an ancestor is reached from its left child.
        ///
        /// # Safety
        ///
        /// `node` and all parent links traversed by this function must be valid.
        unsafe fn parent_with_left<T>(node: NonNull<Node<T>>) -> Link<T> {
            unsafe {
                let parent = node.as_ref().parent;
                if let Some(parent) = parent
                    && let Some(left) = parent.as_ref().left
                {
                    if std::ptr::eq(left.as_ptr(), node.as_ptr()) {
                        return Some(parent);
                    }
                    return parent_with_left(parent);
                }
                // No parent means that the root has been reached.
                None
            }
        }

        /// Iterator over a tree in in-order (`Left -> Node -> Right`, or `LNR`).
        ///
        /// For a binary search tree, this traversal yields values in ascending order.
        pub struct IterInOrder<'a, T> {
            current_node: Link<T>,
            count: usize,
            elem: Option<&'a T>,
            _boo: PhantomData<&'a T>,
        }

        impl<'a, T> IterInOrder<'a, T> {
            /// Creates an in-order iterator starting at `node`.
            pub(crate) fn new(node: Link<T>, count: usize) -> Self {
                Self {
                    current_node: node,
                    count,
                    elem: None,
                    _boo: PhantomData,
                }
            }
        }

        impl<'a, T> Iterator for IterInOrder<'a, T> {
            type Item = &'a T;

            fn next(&mut self) -> Option<Self::Item> {
                if self.count > 0 {
                    self.count -= 1;
                    if let Some(node) = self.current_node {
                        unsafe {
                            self.elem = Some(&node.as_ref().value);
                            self.current_node = successor_of_node_in_order(node);
                        }
                    } else {
                        self.elem = None;
                    }
                } else {
                    self.elem = None;
                }
                self.elem
            }

            fn size_hint(&self) -> (usize, Option<usize>) {
                (self.count, Some(self.count))
            }
        }

        impl<'a, T> ExactSizeIterator for IterInOrder<'a, T> {
            fn len(&self) -> usize {
                self.count
            }
        }

        impl<'a, T> FusedIterator for IterInOrder<'a, T> {}

        /// A lazy iterator over an inclusive range of values in a [`crate::RedBlackTree`].
        ///
        /// `Range` is created by [`crate::RedBlackTree::range`]. It yields references to
        /// values in ascending order, starting from the first value greater than or
        /// equal to the lower bound and stopping after the upper bound.
        ///
        /// The iterator does not allocate an intermediate collection. Values are
        /// produced one at a time as the iterator advances.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([1, 3, 5, 7, 9, 11]);
        ///
        /// let values: Vec<_> = tree
        ///     .range(&3, &9)
        ///     .copied()
        ///     .collect();
        ///
        /// assert_eq!(values, vec![3, 5, 7, 9]);
        /// ```
        ///
        /// The iterator can be combined with standard iterator adapters:
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend(1..=100);
        ///
        /// let values: Vec<_> = tree
        ///     .range(&20, &80)
        ///     .take(3)
        ///     .copied()
        ///     .collect();
        ///
        /// assert_eq!(values, vec![20, 21, 22]);
        /// ```
        pub struct Range<'a, T> {
            current_node: Link<T>,
            end_node: Link<T>,
            _marker: PhantomData<&'a T>,
        }

        impl<'a, T: Ord> Range<'a, T> {
            pub(crate) fn new(root: Link<T>, min: &T, max: &T) -> Self {
                if min > max {
                    return Self {
                        current_node: None,
                        end_node: None,
                        _marker: PhantomData,
                    };
                }

                unsafe {
                    let mut current = root;
                    let mut start: Link<T> = None;

                    // First node >= min.
                    while let Some(node) = current {
                        match node.as_ref().value.cmp(min) {
                            std::cmp::Ordering::Less => {
                                current = node.as_ref().right;
                            }

                            std::cmp::Ordering::Equal => {
                                start = Some(node);
                                break;
                            }

                            std::cmp::Ordering::Greater => {
                                start = Some(node);
                                current = node.as_ref().left;
                            }
                        }
                    }

                    current = root;

                    let mut end: Link<T> = None;

                    // First node > max.
                    while let Some(node) = current {
                        match node.as_ref().value.cmp(max) {
                            std::cmp::Ordering::Less | std::cmp::Ordering::Equal => {
                                current = node.as_ref().right;
                            }

                            std::cmp::Ordering::Greater => {
                                end = Some(node);
                                current = node.as_ref().left;
                            }
                        }
                    }

                    Self {
                        current_node: start,
                        end_node: end,
                        _marker: PhantomData,
                    }
                }
            }
        }

        impl<'a, T> Iterator for Range<'a, T> {
            type Item = &'a T;

            fn next(&mut self) -> Option<Self::Item> {
                let node = self.current_node?;

                if self.end_node == Some(node) {
                    self.current_node = None;
                    return None;
                }

                unsafe {
                    let value = &node.as_ref().value;

                    self.current_node = successor_of_node_in_order(node);

                    Some(value)
                }
            }
        }
    }

    pub use dfs_reverse_in_order::IterReverseInOrder;

    pub(crate) use dfs_reverse_in_order::{
        rightmost_child_reverse_in_order, successor_of_node_reverse_in_order,
    };

    mod dfs_reverse_in_order {
        use super::{Link, Node, NonNull};
        use std::marker::PhantomData;

        /// Returns the next node in reverse in-order (`Right -> Node -> Left`, or `RNL`).
        ///
        /// # Safety
        ///
        /// `node` must point to a live node that belongs to the current tree, and
        /// all parent/child links reachable from it must be valid.
        pub unsafe fn successor_of_node_reverse_in_order<T>(node: NonNull<Node<T>>) -> Link<T> {
            unsafe {
                if node.as_ref().left.is_some() {
                    // After the current node, descend into the left subtree and
                    // choose its rightmost node.
                    rightmost_child_reverse_in_order(node.as_ref().left)
                } else {
                    // Without a left subtree, walk upward until reaching an
                    // ancestor from its right subtree.
                    parent_with_right(node)
                }
            }
        }

        /// Returns the rightmost node reachable from `node`.
        ///
        /// Returns `None` when `node` is `None`.
        ///
        /// # Safety
        ///
        /// Every pointer reachable through `right` links must refer to a live node.
        pub unsafe fn rightmost_child_reverse_in_order<T>(node: Link<T>) -> Link<T> {
            unsafe {
                if let Some(node) = node {
                    if node.as_ref().right.is_none() {
                        Some(node)
                    } else {
                        rightmost_child_reverse_in_order(node.as_ref().right)
                    }
                } else {
                    None
                }
            }
        }

        /// Walks up the parent chain until an ancestor is reached from its right child.
        ///
        /// # Safety
        ///
        /// `node` and all parent links traversed by this function must be valid.
        unsafe fn parent_with_right<T>(node: NonNull<Node<T>>) -> Link<T> {
            unsafe {
                let parent = node.as_ref().parent;

                if let Some(parent) = parent
                    && let Some(right) = parent.as_ref().right
                {
                    if std::ptr::eq(right.as_ptr(), node.as_ptr()) {
                        return Some(parent);
                    }

                    return parent_with_right(parent);
                }

                None
            }
        }

        /// Iterator over a tree in reverse in-order (`Right -> Node -> Left`, or `RNL`).
        ///
        /// For a binary search tree, this traversal yields values in descending order.
        pub struct IterReverseInOrder<'a, T> {
            current_node: Link<T>,
            count: usize,
            elem: Option<&'a T>,
            _boo: PhantomData<&'a T>,
        }

        impl<'a, T> IterReverseInOrder<'a, T> {
            /// Creates a reverse in-order iterator starting at `node`.
            pub(crate) fn new(node: Link<T>, count: usize) -> Self {
                Self {
                    current_node: node,
                    count,
                    elem: None,
                    _boo: PhantomData,
                }
            }
        }

        impl<'a, T> Iterator for IterReverseInOrder<'a, T> {
            type Item = &'a T;

            fn next(&mut self) -> Option<Self::Item> {
                if self.count > 0 {
                    self.count -= 1;

                    if let Some(node) = self.current_node {
                        unsafe {
                            self.elem = Some(&node.as_ref().value);
                            self.current_node = successor_of_node_reverse_in_order(node);
                        }
                    } else {
                        self.elem = None;
                    }
                } else {
                    self.elem = None;
                }

                self.elem
            }

            fn size_hint(&self) -> (usize, Option<usize>) {
                (self.count, Some(self.count))
            }
        }
    }

    pub use dfs_pre_order::IterPreOrder;

    pub(crate) use dfs_pre_order::successor_of_node_pre_order;

    mod dfs_pre_order {
        use super::{Link, Node, NonNull};
        use std::marker::PhantomData;

        /// Returns the next node in a pre-order (`Node -> Left -> Right`, or `NLR`) traversal.
        ///
        /// # Safety
        ///
        /// `node` must point to a live node in the current tree and all traversed
        /// links must be valid.
        pub unsafe fn successor_of_node_pre_order<T>(node: NonNull<Node<T>>) -> Link<T> {
            unsafe {
                if let Some(node) = node.as_ref().left {
                    Some(node)
                } else if let Some(node) = node.as_ref().right {
                    Some(node)
                } else {
                    right_with_parent(node)
                }
            }
        }

        /// Finds the next right subtree by walking through parent links.
        ///
        /// # Safety
        ///
        /// `node` and all parent links traversed by this function must be valid.
        unsafe fn right_with_parent<T>(node: NonNull<Node<T>>) -> Link<T> {
            unsafe {
                if let Some(parent) = node.as_ref().parent {
                    next_right(Some(parent), node)
                } else {
                    None
                }
            }
        }

        /// Searches ancestors for the next unvisited right child.
        ///
        /// # Safety
        ///
        /// `child`, `node`, and all links traversed by this function must be valid.
        unsafe fn next_right<T>(node: Link<T>, child: NonNull<Node<T>>) -> Link<T> {
            unsafe {
                if let Some(n) = node {
                    if let Some(right) = n.as_ref().right {
                        if std::ptr::eq(right.as_ptr(), child.as_ptr()) {
                            next_right(n.as_ref().parent, n)
                        } else {
                            Some(right)
                        }
                    } else {
                        next_right(n.as_ref().parent, n)
                    }
                } else {
                    None
                }
            }
        }

        /// Iterator over a tree in pre-order (`Node -> Left -> Right`, or `NLR`).
        ///
        /// Pre-order traversal visits a node before either of its subtrees.
        pub struct IterPreOrder<'a, T> {
            current_node: Link<T>,
            count: usize,
            elem: Option<&'a T>,
            _boo: PhantomData<&'a T>,
        }

        impl<'a, T> IterPreOrder<'a, T> {
            /// Creates a pre-order iterator starting at `root`.
            pub(crate) fn new(root: Link<T>, count: usize) -> Self {
                Self {
                    current_node: root,
                    count,
                    elem: None,
                    _boo: PhantomData,
                }
            }
        }

        impl<'a, T> Iterator for IterPreOrder<'a, T> {
            type Item = &'a T;

            fn next(&mut self) -> Option<Self::Item> {
                if self.count > 0 {
                    self.count -= 1;
                    if let Some(node) = self.current_node {
                        unsafe {
                            self.elem = Some(&node.as_ref().value);
                            self.current_node = successor_of_node_pre_order(node);
                        }
                    } else {
                        self.elem = None;
                    }
                } else {
                    self.elem = None;
                }
                self.elem
            }

            fn size_hint(&self) -> (usize, Option<usize>) {
                (self.count, Some(self.count))
            }
        }
    }

    pub use dfs_post_order::IterPostOrder;

    pub(crate) use dfs_post_order::{leaf_post_order, successor_of_node_post_order};

    mod dfs_post_order {
        use super::{Link, Node, NonNull};
        use std::marker::PhantomData;

        /// Returns the next node in a post-order (`Left -> Right -> Node`, or `LRN`) traversal.
        ///
        /// # Safety
        ///
        /// `current_node` must point to a live node in the current tree and all
        /// traversed parent/child links must be valid.
        pub unsafe fn successor_of_node_post_order<T>(current_node: NonNull<Node<T>>) -> Link<T> {
            unsafe {
                if let Some(parent) = current_node.as_ref().parent {
                    if let Some(right) = parent.as_ref().right {
                        if std::ptr::eq(current_node.as_ptr(), right.as_ptr()) {
                            Some(parent)
                        } else {
                            Some(leaf_post_order(right))
                        }
                    } else {
                        Some(parent)
                    }
                } else {
                    None
                }
            }
        }

        /// Returns the first leaf visited by a post-order traversal starting at `node`.
        ///
        /// # Safety
        ///
        /// `node` must point to a live node and all descendant links traversed by
        /// this function must be valid.
        pub unsafe fn leaf_post_order<T>(node: NonNull<Node<T>>) -> NonNull<Node<T>> {
            unsafe {
                if let Some(left) = node.as_ref().left {
                    leaf_post_order(left)
                } else if let Some(right) = node.as_ref().right {
                    leaf_post_order(right)
                } else {
                    node
                }
            }
        }

        /// Iterator over a tree in post-order (`Left -> Right -> Node`, or `LRN`).
        ///
        /// Post-order traversal visits both subtrees before the current node.
        pub struct IterPostOrder<'a, T> {
            current_node: Link<T>,
            count: usize,
            _boo: PhantomData<&'a T>,
        }

        impl<'a, T> IterPostOrder<'a, T> {
            /// Creates a post-order iterator starting at the first post-order node.
            pub(crate) fn new(root: Link<T>, count: usize) -> Self {
                Self {
                    current_node: root,
                    count,
                    _boo: PhantomData,
                }
            }
        }

        impl<'a, T> Iterator for IterPostOrder<'a, T> {
            type Item = &'a T;

            fn next(&mut self) -> Option<Self::Item> {
                if self.count == 0 {
                    return None;
                }

                let node = self.current_node?;

                unsafe {
                    let value = &node.as_ref().value;
                    self.current_node = successor_of_node_post_order(node);
                    self.count -= 1;
                    Some(value)
                }
            }

            fn size_hint(&self) -> (usize, Option<usize>) {
                (self.count, Some(self.count))
            }
        }
    }

    /// Breadth-First Search
    mod bfs {
        use super::{Node, NonNull};
        use std::collections::VecDeque;

        /// Appends tree values to `ret` in breadth-first / level-order.
        pub fn iter_level_order_impl<T>(root: NonNull<Node<T>>, ret: &mut Vec<&T>) {
            let mut deque: VecDeque<NonNull<Node<T>>> = VecDeque::new();
            unsafe {
                deque.push_back(root);
                let mut node: NonNull<Node<T>>;
                while !deque.is_empty() {
                    node = deque.pop_front().unwrap();
                    ret.push(&node.as_ref().value);
                    if let Some(left) = node.as_ref().left {
                        deque.push_back(left);
                    }
                    if let Some(right) = node.as_ref().right {
                        deque.push_back(right);
                    }
                }
            }
        }
    }

    pub(crate) use bfs::iter_level_order_impl;
}

/// Internal node representation used by the Red-Black Tree.
///
/// Nodes are allocated on the heap and connected using [`NonNull`] pointers.
/// The tree owns the allocated nodes and is responsible for releasing them.
///
/// `Node` and [`Link`] are crate-private implementation details and are not
/// exposed through the public API.
pub mod node{

    use std::ptr::NonNull;

    /// A single node in the Red-Black Tree.
    ///
    /// Each node stores:
    ///
    /// - a link to its left child;
    /// - a link to its right child;
    /// - a link to its parent;
    /// - its Red-Black color;
    /// - the stored value.
    ///
    /// Tree links are represented by [`Link<T>`], which is an
    /// `Option<NonNull<Node<T>>>`.
    ///
    /// A `None` link represents the absence of a parent or child, while
    /// `Some(pointer)` refers to another allocated node.
    ///
    /// Memory ownership is managed by [`crate::RedBlackTree`]. The pointers stored
    /// here are non-owning links between nodes.
    #[derive(Debug)]
    pub(crate) struct Node<T> {
        /// Left child of this node.
        pub(crate) left: Link<T>,

        /// Right child of this node.
        pub(crate) right: Link<T>,

        /// Parent of this node.
        ///
        /// The root node has no parent.
        pub(crate) parent: Link<T>,

        /// Red-Black color of the node.
        ///
        /// `true` means red and `false` means black.
        pub(crate) is_red: bool,

        /// Value stored in this node.
        pub(crate) value: T,
    }

    /// A link between nodes in the tree.
    ///
    /// `None` represents a missing parent or child.
    ///
    /// `Some(ptr)` contains a non-null pointer to another allocated [`Node`].
    ///
    /// Using `Option<NonNull<Node<T>>>` allows the implementation to represent
    /// nullable tree links while keeping direct pointer-based navigation between
    /// parents and children.
    pub(crate) type Link<T> = Option<NonNull<Node<T>>>;

    impl<T: Default> Node<T> {
        /// Creates the sentinel head node together with the initial tree root.
        ///
        /// The sentinel does not represent a value stored by the user. Its
        /// `value` field is initialized with [`Default::default`] and its left
        /// child becomes the first actual node in the tree.
        ///
        /// The initial root node is created as black, as required by the
        /// Red-Black Tree invariants.
        ///
        /// # Returns
        ///
        /// A link to the newly allocated sentinel node.
        ///
        /// # Implementation
        ///
        /// Both the sentinel and the root node are allocated on the heap.
        /// Ownership of these allocations is transferred to the tree and later
        /// recovered when the tree releases its nodes.
        pub(crate) fn new_fixed_head(value: T) -> Link<T> {
            let fixed_head = Box::into_non_null(Box::new(Self {
                left: None,
                right: None,
                parent: None,
                is_red: false,
                value: T::default(),
            }));
            unsafe {
                (*fixed_head.as_ptr()).left = Node::new_black(value);
            }
            Some(fixed_head)
        }
    }

    impl<T> Node<T> {
        /// Allocates a new black node.
        ///
        /// The node is created without a parent or children.
        ///
        /// # Returns
        ///
        /// A non-null link to the newly allocated node.
        ///
        /// The allocation becomes owned by the tree and must eventually be
        /// released by the tree implementation.
        pub(crate) fn new_black(value: T) -> Link<T> {
            let new = Box::into_non_null(Box::new(Self {
                left: None,
                right: None,
                parent: None,
                is_red: false,
                value,
            }));

            Some(new)
        }

        /// Allocates a new red node with the specified parent.
        ///
        /// Newly inserted Red-Black Tree nodes are initially red. The balancing
        /// algorithm may later recolor the node or rotate the surrounding
        /// subtree.
        ///
        /// The new node has no children.
        ///
        /// # Parameters
        ///
        /// - `value` — value stored in the node.
        /// - `parent` — non-null pointer to the node's parent.
        ///
        /// # Returns
        ///
        /// A non-null link to the newly allocated node.
        ///
        /// The allocation becomes owned by the tree and must eventually be
        /// released by the tree implementation.
        pub(crate) fn new_red(value: T, parent: NonNull<Node<T>>) -> Link<T> {
            let new = Box::into_non_null(Box::new(Self {
                left: None,
                right: None,
                parent: Some(parent),
                is_red: true,
                value,
            }));

            Some(new)
        }
    }
}


pub mod validation{
    use crate::node::Link;
    use crate::tree::RedBlackTree;

    impl<T: Ord + Default> RedBlackTree<T> {
        // red-red violations,
        // min black-height,
        // max black-height,
        // BST ordering,
        // parent links,
        // reachable node count
        unsafe fn validate(
            node: &Link<T>,
            expected_parent: Link<T>,
            parent_is_red: bool,
            black_height: usize,
            min: Option<&T>,
            max: Option<&T>,
        ) -> (usize, usize, usize, bool, bool, usize) {
            unsafe {
                if let Some(n) = node {
                    let value = &n.as_ref().value;

                    // 1. Check parent
                    let parent_valid = match (n.as_ref().parent, expected_parent) {
                        (None, None) => true,

                        (Some(actual), Some(expected)) => {
                            std::ptr::eq(actual.as_ptr(), expected.as_ptr())
                        }

                        _ => false,
                    };

                    // 2. Check BST ordering
                    if let Some(min) = min
                        && value <= min
                    {
                        return (0, 0, 0, false, parent_valid, 1);
                    }

                    if let Some(max) = max
                        && value >= max
                    {
                        return (0, 0, 0, false, parent_valid, 1);
                    }

                    let is_red = n.as_ref().is_red;

                    // 3. A red node cannot have a red parent.
                    let red_red = if parent_is_red && is_red { 1 } else { 0 };

                    // 4. Black height
                    let black_height = if is_red {
                        black_height
                    } else {
                        black_height + 1
                    };

                    let left = Self::validate(
                        &n.as_ref().left,
                        Some(*n),
                        is_red,
                        black_height,
                        min,
                        Some(value),
                    );

                    let right = Self::validate(
                        &n.as_ref().right,
                        Some(*n),
                        is_red,
                        black_height,
                        Some(value),
                        max,
                    );

                    (
                        red_red + left.0 + right.0,
                        std::cmp::min(left.1, right.1),
                        std::cmp::max(left.2, right.2),
                        left.3 && right.3,
                        parent_valid && left.4 && right.4,
                        1 + left.5 + right.5,
                    )
                } else {
                    (0, black_height, black_height, true, true, 0)
                }
            }
        }

        pub fn is_valid(&self) -> bool {
            unsafe {
                // tree is empty
                if self.count == 0 {
                    return match self.fixed_head {
                        None => true,

                        Some(fixed_head) => (*fixed_head.as_ptr()).left.is_none(),
                    };
                }

                // count > 0, so sentinel must exist.
                let Some(fixed_head) = self.fixed_head else {
                    return false;
                };

                // And root must exist.
                let root_link = (*fixed_head.as_ptr()).left;

                let Some(root) = root_link else {
                    return false;
                };

                // Root is always BLACK
                if root.as_ref().is_red {
                    return false;
                }

                // Root has no parent
                if root.as_ref().parent.is_some() {
                    return false;
                }

                let result = Self::validate(&root_link, None, false, 0, None, None);

                let red_red = result.0;
                let black_height_min = result.1;
                let black_height_max = result.2;
                let bst_valid = result.3;
                let parents_valid = result.4;
                let reachable_nodes = result.5;

                red_red == 0
                    && black_height_min == black_height_max
                    && bst_valid
                    && parents_valid
                    && reachable_nodes == self.count
            }
        }
    }
}


pub mod tree{
    use std::cmp::Ordering;
    use std::fmt::{Debug, Display};

    use crate::node::{Link, Node};

    use std::marker::PhantomData;
    use std::ptr::NonNull;

    use crate::iter::{IterInOrder, Range, leftmost_child_in_order, successor_of_node_in_order};

    use crate::iter::{
        IterReverseInOrder, rightmost_child_reverse_in_order, successor_of_node_reverse_in_order,
    };

    use crate::iter::{IterPreOrder, successor_of_node_pre_order};

    use crate::iter::{IterPostOrder, leaf_post_order, successor_of_node_post_order};

    use crate::iter::iter_level_order_impl;

    /// A self-balancing Red-Black Tree.
    ///
    /// `RedBlackTree` stores unique values in sorted order.
    ///
    /// Insert, lookup and removal operations have logarithmic
    /// expected tree height due to Red-Black Tree balancing.
    ///
    /// # Examples
    ///
    /// ```
    /// use rbtree_extended::RedBlackTree;
    ///
    /// let mut tree = RedBlackTree::new();
    ///
    /// tree.insert(3);
    /// tree.insert(1);
    /// tree.insert(2);
    ///
    /// assert_eq!(tree.len(), 3);
    /// assert!(tree.contains(&2));
    /// ```
    pub struct RedBlackTree<T: Ord + Default> {
        pub(crate) fixed_head: Link<T>,
        pub(crate) count: usize,
        _marker: PhantomData<T>,
    }

    enum OperationPut {
        Left,
        Right,
        FlipColors,
        Nothing,
    }

    enum OperationRemove {
        RedLeaf,
        BlackLeaf,
        NodeWithChildren,
        BlackNodeWithRedLeaf,
    }

    enum OperationRemoveBlackLeaf {
        LeftRedABlackBRedCleaf,                      // 2.1.1.1
        RightRedABlackBRedCleaf,                     // 2.1.1.2
        LeftRedABlackBleaf,                          // 2.1.2.1
        RightRedABlackBleaf,                         // 2.1.2.2
        BlackARedBWithBlackChildrenLeaf,             // 2.2.4
        BlackARedBWithBlackChildrenRightHaveRedLeaf, // 2.2.1
        BlackALeftBlackBRedDleaf,                    // 2.3.1.1
        BlackARightBlackBRedDleaf,                   // 2.3.1.2
        BlackALeftBlackBleaf,                        // 2.3.2.1
        BlackARightBlackBleaf,                       // 2.3.2.2
        Root,
        Unimplemented,
    }

    impl<T: Ord + Default + Display> RedBlackTree<T> {
        /// Exports the tree in Graphviz DOT format.
        ///
        /// The returned string can be rendered using Graphviz-compatible tools.
        ///
        /// An empty tree produces a valid empty DOT graph.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.insert(10);
        /// tree.insert(5);
        /// tree.insert(20);
        ///
        /// let dot = tree.to_dot();
        ///
        /// println!("{dot}");
        /// ```
        pub fn to_dot(&self) -> String {
            unsafe {
                let Some(fixed_head) = self.fixed_head else {
                    return "digraph Tree {}".into();
                };

                let Some(root) = (*fixed_head.as_ptr()).left else {
                    return "digraph Tree {}".into();
                };

                format!(
                    "\ndigraph Tree {{\n\tratio = fill;\n\tnode [style=filled fontcolor=\"white\"];\n{}}}",
                    helper_display_tree(root)
                )
            }
        }
    }

    impl<T: Ord + Default> RedBlackTree<T> {
        /// Creates an empty Red-Black Tree.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let tree = RedBlackTree::<i32>::new();
        ///
        /// assert!(tree.is_empty());
        /// ```
        pub fn new() -> Self {
            Self {
                fixed_head: None,
                count: 0,
                _marker: PhantomData,
            }
        }

        /// Returns the number of values stored in the tree.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.insert(10);
        /// tree.insert(20);
        ///
        /// assert_eq!(tree.len(), 2);
        /// ```
        pub fn len(&self) -> usize {
            self.count
        }

        /// Returns `true` if the tree contains no values.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::<i32>::new();
        /// assert!(tree.is_empty());
        ///
        /// tree.insert(10);
        /// assert!(!tree.is_empty());
        /// ```
        pub fn is_empty(&self) -> bool {
            self.count == 0
        }

        /// Removes all values from the tree.
        ///
        /// After calling `clear`, the tree is empty and can be reused.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([1, 2, 3]);
        ///
        /// tree.clear();
        ///
        /// assert!(tree.is_empty());
        /// assert_eq!(tree.len(), 0);
        /// ```
        pub fn clear(&mut self) {
            unsafe {
                if let Some(fixed_head) = self.fixed_head {
                    let root = (*fixed_head.as_ptr()).left;

                    (*fixed_head.as_ptr()).left = None;

                    self.remove_tree(root);
                }

                debug_assert_eq!(self.count, 0);
            }
        }

        /// Returns the smallest value in the tree.
        ///
        /// Returns `None` if the tree is empty.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([8, 3, 10, 1]);
        ///
        /// assert_eq!(tree.first(), Some(&1));
        /// ```
        pub fn first(&self) -> Option<&T> {
            self.minimum()
        }

        /// Returns the largest value in the tree.
        ///
        /// Returns `None` if the tree is empty.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([8, 3, 10, 14]);
        ///
        /// assert_eq!(tree.last(), Some(&14));
        /// ```
        pub fn last(&self) -> Option<&T> {
            self.maximum()
        }

        fn minimum(&self) -> Option<&T> {
            unsafe {
                let root = self.get_root()?;
                let node = self.find_min(root);
                Some(&node.as_ref().value)
            }
        }

        fn maximum(&self) -> Option<&T> {
            unsafe {
                let root = self.get_root()?;
                let node = self.find_max(root);

                Some(&node.as_ref().value)
            }
        }

        /// Returns the height of the tree.
        ///
        /// An empty tree has height `0`.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// assert_eq!(tree.height(), 0);
        ///
        /// tree.insert(10);
        /// assert_eq!(tree.height(), 1);
        /// ```
        pub fn height(&self) -> usize {
            unsafe fn height_from<T>(node: Link<T>) -> usize {
                unsafe {
                    match node {
                        None => 0,

                        Some(node) => {
                            let left_height = height_from(node.as_ref().left);
                            let right_height = height_from(node.as_ref().right);

                            1 + left_height.max(right_height)
                        }
                    }
                }
            }

            unsafe { height_from(self.get_root()) }
        }

        /// Returns `true` if the tree contains `value`.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([1, 3, 5]);
        ///
        /// assert!(tree.contains(&3));
        /// assert!(!tree.contains(&4));
        /// ```
        pub fn contains(&self, value: &T) -> bool {
            !find_node(self.get_root(), value).is_none()
        }

        /// Inserts a value into the tree.
        ///
        /// Returns `true` if the value was inserted.
        ///
        /// Returns `false` if the value already exists.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        ///
        /// assert!(tree.insert(10));
        /// assert!(!tree.insert(10));
        /// ```
        pub fn insert(&mut self, value: T) -> bool {
            unsafe {
                if let Some(fixed_head) = self.fixed_head {
                    if (*fixed_head.as_ptr()).left.is_none() {
                        (*fixed_head.as_ptr()).left = Node::new_black(value);
                        self.count += 1;
                        return true;
                    }

                    let parent = self.find_put_parent_candidate(self.get_root(), &value);

                    if let Some(parent) = parent {
                        if self.attach_node(parent, value) {
                            self.put_balancing(parent);
                        } else {
                            return false;
                        }
                    } else {
                        return false;
                    }
                } else {
                    self.fixed_head = Node::new_fixed_head(value);
                }

                self.count += 1;
                true
            }
        }

        /// Removes a value from the tree.
        ///
        /// Returns `true` if the value existed and was removed.
        ///
        /// Use [`RedBlackTree::take`] when ownership of the removed value is needed.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.insert(10);
        ///
        /// assert!(tree.remove(&10));
        /// assert!(!tree.contains(&10));
        /// assert!(!tree.remove(&10));
        /// ```
        pub fn remove(&mut self, value: &T) -> bool {
            self.take(value).is_some()
        }

        /// Inserts `value` into the tree, replacing an existing equal value.
        ///
        /// If the tree already contains a value that compares equal to `value`,
        /// the existing value is replaced and returned.
        ///
        /// If no equal value exists, `value` is inserted and `None` is returned.
        ///
        /// This is especially useful for custom types whose [`Ord`] implementation
        /// compares only a key field.
        ///
        /// # Examples
        ///
        /// ```
        /// use std::cmp::Ordering;
        /// use rbtree_extended::RedBlackTree;
        ///
        /// #[derive(Debug, Default)]
        /// struct User {
        ///     id: u32,
        ///     name: String,
        /// }
        ///
        /// impl PartialEq for User {
        ///     fn eq(&self, other: &Self) -> bool {
        ///         self.id == other.id
        ///     }
        /// }
        ///
        /// impl Eq for User {}
        ///
        /// impl PartialOrd for User {
        ///     fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        ///         Some(self.cmp(other))
        ///     }
        /// }
        ///
        /// impl Ord for User {
        ///     fn cmp(&self, other: &Self) -> Ordering {
        ///         self.id.cmp(&other.id)
        ///     }
        /// }
        ///
        /// let mut users = RedBlackTree::new();
        ///
        /// users.insert(User {
        ///     id: 1,
        ///     name: "Alice".into(),
        /// });
        ///
        /// let old = users.replace(User {
        ///     id: 1,
        ///     name: "Bob".into(),
        /// });
        ///
        /// assert_eq!(old.unwrap().name, "Alice");
        /// assert_eq!(users.first().unwrap().name, "Bob");
        /// ```
        pub fn replace(&mut self, value: T) -> Option<T> {
            unsafe {
                if let Some(mut node) = find_node(self.get_root(), &value) {
                    return Some(std::mem::replace(&mut node.as_mut().value, value));
                }
            }

            self.insert(value);

            None
        }

        unsafe fn take_node(&mut self, mut node: NonNull<Node<T>>) -> Option<T> {
            unsafe {
                // Save the original value before the internal removal algorithm
                // starts swapping values between nodes.
                let removed_value = std::mem::take(&mut node.as_mut().value);

                if !self.remove_node(node) {
                    return None;
                }

                self.count -= 1;

                Some(removed_value)
            }
        }

        /// Removes and returns the value equal to `value`.
        ///
        /// Returns `None` if the value is not present in the tree.
        ///
        /// Unlike [`RedBlackTree::remove`], this method gives ownership of the
        /// removed value back to the caller.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([10, 5, 20]);
        ///
        /// assert_eq!(tree.take(&10), Some(10));
        /// assert!(!tree.contains(&10));
        /// assert_eq!(tree.take(&100), None);
        /// ```
        pub fn take(&mut self, value: &T) -> Option<T> {
            if self.is_empty() {
                return None;
            }

            unsafe {
                let node = find_node(self.get_root(), value)?;
                self.take_node(node)
            }
        }

        /// Retains only the values specified by the predicate.
        ///
        /// In other words, removes every value for which `f(&value)` returns `false`.
        ///
        /// The predicate receives a shared reference to each stored value.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([1, 2, 3, 4, 5, 6]);
        ///
        /// tree.retain(|value| value % 2 == 0);
        ///
        /// assert_eq!(
        ///     tree.iter().copied().collect::<Vec<_>>(),
        ///     vec![2, 4, 6]
        /// );
        /// ```
        ///
        /// Retaining no values empties the tree:
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([1, 2, 3]);
        ///
        /// tree.retain(|_| false);
        ///
        /// assert!(tree.is_empty());
        /// ```
        pub fn retain<F>(&mut self, mut f: F)
        where
            F: FnMut(&T) -> bool,
        {
            let mut retained = Self::new();

            while let Some(value) = self.pop_first() {
                if f(&value) {
                    retained.insert(value);
                }
            }

            *self = retained;
        }

        /// Removes and returns the smallest value in the tree.
        ///
        /// Returns `None` if the tree is empty.
        ///
        /// This operation is useful when values need to be processed in
        /// ascending order.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([8, 3, 10, 1, 6]);
        ///
        /// assert_eq!(tree.pop_first(), Some(1));
        /// assert_eq!(tree.pop_first(), Some(3));
        /// assert_eq!(tree.len(), 3);
        /// ```
        pub fn pop_first(&mut self) -> Option<T> {
            unsafe {
                let root = self.get_root()?;
                let node = self.find_min(root);

                self.take_node(node)
            }
        }

        /// Removes and returns the largest value in the tree.
        ///
        /// Returns `None` if the tree is empty.
        ///
        /// This operation can be used to implement a priority queue where the
        /// greatest value represents the highest priority.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([8, 3, 10, 1, 6]);
        ///
        /// assert_eq!(tree.pop_last(), Some(10));
        /// assert_eq!(tree.pop_last(), Some(8));
        /// assert_eq!(tree.len(), 3);
        /// ```
        pub fn pop_last(&mut self) -> Option<T> {
            unsafe {
                let root = self.get_root()?;
                let node = self.find_max(root);

                self.take_node(node)
            }
        }

        /// Returns a reference to the stored value equal to `value`.
        ///
        /// Returns `None` if no matching value exists.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([1, 3, 5]);
        ///
        /// assert_eq!(tree.get(&3), Some(&3));
        /// assert_eq!(tree.get(&4), None);
        /// ```
        pub fn get(&self, value: &T) -> Option<&T> {
            unsafe {
                let node = find_node(self.get_root(), value)?;
                Some(&node.as_ref().value)
            }
        }

        /// Returns the next greater value in sorted order.
        ///
        /// Returns `None` if `value` is not present or if it is the largest value.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([1, 3, 5, 7]);
        ///
        /// assert_eq!(tree.successor(&3), Some(&5));
        /// assert_eq!(tree.successor(&7), None);
        /// ```
        pub fn successor(&self, value: &T) -> Option<&T> {
            unsafe {
                let node = find_node(self.get_root(), value)?;

                // Case 1:
                // there is a right subtree - successor = minimum element on the right
                if let Some(right) = node.as_ref().right {
                    let successor = self.find_min(right);
                    return Some(&successor.as_ref().value);
                }

                // Case 2:
                // there is no right subtree
                // Move up while the current node is a right child
                let mut current = node;
                let mut parent = current.as_ref().parent;

                while let Some(p) = parent {
                    if let Some(left) = p.as_ref().left
                        && std::ptr::eq(left.as_ptr(), current.as_ptr())
                    {
                        return Some(&p.as_ref().value);
                    }

                    current = p;
                    parent = p.as_ref().parent;
                }

                None
            }
        }

        /// Returns the previous smaller value in sorted order.
        ///
        /// Returns `None` if `value` is not present or if it is the smallest value.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([1, 3, 5, 7]);
        ///
        /// assert_eq!(tree.predecessor(&5), Some(&3));
        /// assert_eq!(tree.predecessor(&1), None);
        /// ```
        pub fn predecessor(&self, value: &T) -> Option<&T> {
            unsafe {
                let node = find_node(self.get_root(), value)?;

                // Case 1:
                // there is a left subtree - predecessor = maximum element on the left
                if let Some(left) = node.as_ref().left {
                    let predecessor = self.find_max(left);
                    return Some(&predecessor.as_ref().value);
                }

                // Case 2:
                // there is no left subtree
                // Move up while the current node is a left child
                let mut current = node;
                let mut parent = current.as_ref().parent;

                while let Some(p) = parent {
                    if let Some(right) = p.as_ref().right
                        && std::ptr::eq(right.as_ptr(), current.as_ptr())
                    {
                        return Some(&p.as_ref().value);
                    }

                    current = p;
                    parent = p.as_ref().parent;
                }

                None
            }
        }

        /// Returns the first value greater than or equal to `value`.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([1, 3, 6, 8]);
        ///
        /// assert_eq!(tree.lower_bound(&5), Some(&6));
        /// assert_eq!(tree.lower_bound(&6), Some(&6));
        /// ```
        pub fn lower_bound(&self, value: &T) -> Option<&T> {
            unsafe {
                let mut current = self.get_root();
                let mut candidate: Link<T> = None;

                while let Some(node) = current {
                    match node.as_ref().value.cmp(value) {
                        Ordering::Less => {
                            current = node.as_ref().right;
                        }

                        Ordering::Equal => {
                            return Some(&node.as_ref().value);
                        }

                        Ordering::Greater => {
                            candidate = Some(node);
                            current = node.as_ref().left;
                        }
                    }
                }

                candidate.map(|node| &node.as_ref().value)
            }
        }

        /// Returns the first value strictly greater than `value`.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([1, 3, 6, 8]);
        ///
        /// assert_eq!(tree.upper_bound(&6), Some(&8));
        /// assert_eq!(tree.upper_bound(&8), None);
        /// ```
        pub fn upper_bound(&self, value: &T) -> Option<&T> {
            unsafe {
                let mut current = self.get_root();
                let mut candidate: Link<T> = None;

                while let Some(node) = current {
                    match node.as_ref().value.cmp(value) {
                        Ordering::Less | Ordering::Equal => {
                            current = node.as_ref().right;
                        }
                        Ordering::Greater => {
                            candidate = Some(node);
                            current = node.as_ref().left;
                        }
                    }
                }

                candidate.map(|node| &node.as_ref().value)
            }
        }

        /// Returns an iterator over values in the inclusive range `[min, max]`.
        ///
        /// Values are yielded in ascending order.
        ///
        /// The iterator is lazy: values are produced only as they are requested,
        /// rather than being collected into an intermediate `Vec`.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([1, 3, 5, 7, 9, 11]);
        ///
        /// let values: Vec<_> = tree
        ///     .range(&3, &9)
        ///     .copied()
        ///     .collect();
        ///
        /// assert_eq!(values, vec![3, 5, 7, 9]);
        /// ```
        pub fn range(&self, min: &T, max: &T) -> Range<'_, T> {
            Range::new(self.get_root(), min, max)
        }

        /// Returns the next value in an in-order (`LNR`) traversal.
        ///
        /// For a binary search tree, in-order traversal visits values in ascending order.
        ///
        /// Returns `None` if `value` is not present or has no successor in this traversal.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([4, 2, 6, 1, 3, 5, 7]);
        ///
        /// assert_eq!(tree.successor_dfs_in_order(4), Some(&5));
        /// ```
        pub fn successor_dfs_in_order(&self, value: T) -> Option<&T> {
            unsafe {
                let node = find_node(self.get_root(), &value);
                if let Some(n) = node
                    && let Some(nodesucc) = successor_of_node_in_order(n)
                {
                    return Some(&nodesucc.as_ref().value);
                }
                None
            }
        }

        /// Returns the next value in reverse in-order (`RNL`) traversal.
        ///
        /// For a binary search tree, reverse in-order traversal visits values in
        /// descending order.
        ///
        /// Returns `None` if `value` is not present or has no successor in this traversal.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([4, 2, 6, 1, 3, 5, 7]);
        ///
        /// assert_eq!(tree.successor_dfs_reverse_in_order(6), Some(&5));
        /// ```
        pub fn successor_dfs_reverse_in_order(&self, value: T) -> Option<&T> {
            unsafe {
                if let Some(node) = find_node(self.get_root(), &value)
                    && let Some(next) = successor_of_node_reverse_in_order(node)
                {
                    return Some(&next.as_ref().value);
                }
                None
            }
        }

        /// Returns the next value in post-order (`LRN`) traversal.
        ///
        /// Post-order visits the left subtree, then the right subtree,
        /// and finally the current node.
        ///
        /// Returns `None` if `value` is not present or has no successor in this traversal.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([4, 2, 6, 1, 3, 5, 7]);
        ///
        /// // Post-order: 1, 3, 2, 5, 7, 6, 4
        /// assert_eq!(tree.successor_dfs_post_order(3), Some(&2));
        /// assert_eq!(tree.successor_dfs_post_order(2), Some(&5));
        /// assert_eq!(tree.successor_dfs_post_order(4), None);
        /// ```
        pub fn successor_dfs_post_order(&self, value: T) -> Option<&T> {
            unsafe {
                if let Some(n) = find_node(self.get_root(), &value)
                    && let Some(nodesucc) = successor_of_node_post_order(n)
                {
                    return Some(&nodesucc.as_ref().value);
                }
                None
            }
        }

        /// Returns the next value in pre-order (`NLR`) traversal.
        ///
        /// Pre-order visits the current node first, followed by the left and right
        /// subtrees.
        ///
        /// Returns `None` if `value` is not present or has no successor in this traversal.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([4, 2, 6, 1, 3, 5, 7]);
        ///
        /// let first = *tree.iter_preorder().next().unwrap();
        /// assert_eq!(tree.successor_dfs_pre_order(first), tree.iter_preorder().nth(1));
        /// ```
        pub fn successor_dfs_pre_order(&self, value: T) -> Option<&T> {
            unsafe {
                if let Some(n) = find_node(self.get_root(), &value)
                    && let Some(nodesucc) = successor_of_node_pre_order(n)
                {
                    return Some(&nodesucc.as_ref().value);
                }
                None
            }
        }

        fn get_root(&self) -> Link<T> {
            if let Some(fixed_head) = self.fixed_head {
                unsafe { (*fixed_head.as_ptr()).left }
            } else {
                None
            }
        }

        unsafe fn operation_remove(&self, node_x: &NonNull<Node<T>>) -> OperationRemove {
            unsafe {
                if node_x.as_ref().is_red
                    && node_x.as_ref().left.is_none()
                    && node_x.as_ref().right.is_none()
                {
                    return OperationRemove::RedLeaf;
                }
                if node_x.as_ref().is_red
                    && node_x.as_ref().left.is_some()
                    && node_x.as_ref().right.is_some()
                {
                    return OperationRemove::NodeWithChildren;
                }
                if !node_x.as_ref().is_red {
                    if node_x.as_ref().left.is_some() && node_x.as_ref().right.is_some() {
                        return OperationRemove::NodeWithChildren;
                    } else if node_x.as_ref().left.is_some() && node_x.as_ref().right.is_none() {
                        if let Some(left) = node_x.as_ref().left
                            && left.as_ref().is_red
                            && left.as_ref().left.is_none()
                            && left.as_ref().right.is_none()
                        {
                            return OperationRemove::BlackNodeWithRedLeaf;
                        }
                    } else if node_x.as_ref().left.is_none() && node_x.as_ref().right.is_none() {
                        return OperationRemove::BlackLeaf;
                    }
                }
                panic!();
            }
        }

        unsafe fn operation_remove_black_leaf(
            &self,
            node_x: &NonNull<Node<T>>,
        ) -> OperationRemoveBlackLeaf {
            unsafe {
                if let Some(node_a) = node_x.as_ref().parent {
                    if node_a.as_ref().is_red {
                        if let Some(node_b) = node_a.as_ref().left
                            && !std::ptr::eq(node_b.as_ptr(), node_x.as_ptr())
                            && !node_b.as_ref().is_red
                        {
                            if let Some(node_c) = node_b.as_ref().left
                                && node_c.as_ref().is_red
                            {
                                return OperationRemoveBlackLeaf::LeftRedABlackBRedCleaf;
                                // 2.1.1.1
                            }

                            // sibling B is black and its left child is either absent or also black
                            return OperationRemoveBlackLeaf::LeftRedABlackBleaf;
                            // 2.1.2.1
                        }

                        if let Some(node_b) = node_a.as_ref().right
                            && !std::ptr::eq(node_b.as_ptr(), node_x.as_ptr())
                            && !node_b.as_ref().is_red
                        {
                            if let Some(node_c) = node_b.as_ref().left
                                && node_c.as_ref().is_red
                            {
                                return OperationRemoveBlackLeaf::RightRedABlackBRedCleaf;
                                // 2.1.1.2
                            }

                            // sibling B is black and its left child is either absent or also black
                            return OperationRemoveBlackLeaf::RightRedABlackBleaf;
                            // 2.1.2.2
                        }
                    } else {
                        if let Some(node_b) = node_a.as_ref().left
                            && !std::ptr::eq(node_b.as_ptr(), node_x.as_ptr())
                        {
                            if node_b.as_ref().is_red && node_b.as_ref().right.is_some() {
                                let node_c = node_b.as_ref().right.unwrap();
                                if !node_c.as_ref().is_red {
                                    if node_c.as_ref().left.is_some()
                                        && let Some(node_d) = node_c.as_ref().left
                                        && node_d.as_ref().is_red
                                    {
                                        return OperationRemoveBlackLeaf::BlackARedBWithBlackChildrenRightHaveRedLeaf;
                                        // 2.2.1
                                    }
                                    return OperationRemoveBlackLeaf::BlackARedBWithBlackChildrenLeaf;
                                    // 2.2.2
                                }
                            }
                            if !node_b.as_ref().is_red
                                && node_b.as_ref().left.is_some()
                                && let Some(node_d) = node_b.as_ref().left
                                && node_d.as_ref().is_red
                            {
                                return OperationRemoveBlackLeaf::BlackALeftBlackBRedDleaf;
                                // 2.3.1.1
                            }
                            if !node_b.as_ref().is_red {
                                return OperationRemoveBlackLeaf::BlackALeftBlackBleaf;
                                // 2.3.2.1
                            }
                        }
                        if let Some(node_b) = node_a.as_ref().right
                            && !std::ptr::eq(node_b.as_ptr(), node_x.as_ptr())
                        {
                            if !node_b.as_ref().is_red
                                && node_b.as_ref().left.is_some()
                                && let Some(node_d) = node_b.as_ref().left
                                && node_d.as_ref().is_red
                            {
                                return OperationRemoveBlackLeaf::BlackARightBlackBRedDleaf;
                                // 2.3.1.2
                            }
                            if !node_b.as_ref().is_red {
                                return OperationRemoveBlackLeaf::BlackARightBlackBleaf;
                                // 2.3.2.2
                            }
                        }
                    }
                } else {
                    return OperationRemoveBlackLeaf::Root;
                }
                OperationRemoveBlackLeaf::Unimplemented
            }
        }

        unsafe fn remove_black_leaf(&mut self, node_x: NonNull<Node<T>>) -> bool {
            unsafe {
                let mut next = node_x;
                let mut removed = false;
                loop {
                    match self.operation_remove_black_leaf(&next) {
                        OperationRemoveBlackLeaf::LeftRedABlackBRedCleaf => {
                            self.remove_black_leaf_2_1_1_1_balancing(&next);
                            if !removed {
                                removed = self.remove_leaf(node_x);
                            }
                            break;
                        }
                        OperationRemoveBlackLeaf::RightRedABlackBRedCleaf => {
                            self.remove_black_leaf_2_1_1_2_balancing(&next);
                            if !removed {
                                removed = self.remove_leaf(node_x);
                            }
                            break;
                        }
                        OperationRemoveBlackLeaf::LeftRedABlackBleaf => {
                            self.remove_black_leaf_2_1_2_1_balancing(&next);
                            if !removed {
                                removed = self.remove_leaf(node_x);
                            }
                            break;
                        }
                        OperationRemoveBlackLeaf::RightRedABlackBleaf => {
                            self.remove_black_leaf_2_1_2_2_balancing(&next);
                            if !removed {
                                removed = self.remove_leaf(node_x);
                            }
                            break;
                        }
                        OperationRemoveBlackLeaf::BlackARedBWithBlackChildrenRightHaveRedLeaf => {
                            self.remove_black_leaf_2_2_1_balancing(&next);
                            if !removed {
                                removed = self.remove_leaf(node_x);
                            }
                            break;
                        }
                        OperationRemoveBlackLeaf::BlackARedBWithBlackChildrenLeaf => {
                            self.remove_black_leaf_2_2_2_balancing(&next);
                            if !removed {
                                removed = self.remove_leaf(node_x);
                            }
                            break;
                        }
                        OperationRemoveBlackLeaf::BlackALeftBlackBRedDleaf => {
                            self.remove_black_leaf_2_3_1_1_balancing(&next);
                            if !removed {
                                removed = self.remove_leaf(node_x);
                            }
                            break;
                        }
                        OperationRemoveBlackLeaf::BlackARightBlackBRedDleaf => {
                            self.remove_black_leaf_2_3_1_2_balancing(&next);
                            if !removed {
                                removed = self.remove_leaf(node_x);
                            }
                            break;
                        }
                        OperationRemoveBlackLeaf::BlackALeftBlackBleaf => {
                            next = self.remove_black_leaf_2_3_2_1_balancing(&next);
                            if !removed {
                                removed = self.remove_leaf(node_x);
                            }
                        }
                        OperationRemoveBlackLeaf::BlackARightBlackBleaf => {
                            next = self.remove_black_leaf_2_3_2_2_balancing(&next);
                            if !removed {
                                removed = self.remove_leaf(node_x);
                            }
                        }
                        OperationRemoveBlackLeaf::Root => {
                            if !removed {
                                // We get here when the node_x being deleted is root
                                if let Some(fixed_head) = self.fixed_head {
                                    (*fixed_head.as_ptr()).left = None;
                                }
                                let _ = Box::from_raw(node_x.as_ptr());
                                removed = true;
                            }
                            break;
                        }
                        OperationRemoveBlackLeaf::Unimplemented => {
                            panic!("unimplemented black leaf removal case");
                        }
                    }
                }
                removed
            }
        }

        /// 2.1.1.1 remove black X
        ///
        /// ```text
        ///             P            P
        ///            //           //
        ///            A            B
        ///           / \          / \
        ///          B   X   =>   C   A
        ///         //\              /
        ///        C   D            D
        /// ```
        unsafe fn remove_black_leaf_2_1_1_1_balancing(&mut self, node_x: &NonNull<Node<T>>) {
            unsafe {
                let node_a = (*node_x.as_ptr()).parent.unwrap();
                let node_b = (*node_a.as_ptr()).left.unwrap();
                let node_d = (*node_b.as_ptr()).right;
                (*node_b.as_ptr()).parent = (*node_a.as_ptr()).parent;
                if let Some(ref mut parent) = (*node_b.as_ptr()).parent {
                    (*parent.as_ptr()).left = Some(node_b);
                }
                (*node_a.as_ptr()).left = node_d;
                if let Some(n_d) = node_d {
                    (*n_d.as_ptr()).parent = Some(node_a);
                }
                (*node_a.as_ptr()).is_red = false;
                (*node_b.as_ptr()).right = Some(node_a);
                (*node_a.as_ptr()).parent = Some(node_b);
                (*node_b.as_ptr()).is_red = true;
                if let Some(node_c) = (*node_b.as_ptr()).left {
                    (*node_c.as_ptr()).is_red = false;
                }
            }
        }

        /// 2.1.1.2 remove black X
        ///
        /// ```text
        ///             P              P
        ///            //             //
        ///           A               C
        ///          / \            /   \
        ///         X   B   =>     A     B
        ///            //           \   /
        ///            C             E D
        ///           / \
        ///          E   D
        /// ```
        unsafe fn remove_black_leaf_2_1_1_2_balancing(&mut self, node_x: &NonNull<Node<T>>) {
            unsafe {
                let node_a = (*node_x.as_ptr()).parent.unwrap();
                (*node_a.as_ptr()).is_red = false;
                let parent: NonNull<Node<T>> = (*node_a.as_ptr()).parent.unwrap();
                let node_b = (*node_a.as_ptr()).right.unwrap();
                let node_c = (*node_b.as_ptr()).left.unwrap();
                let node_e = (*node_c.as_ptr()).left;
                let node_d = (*node_c.as_ptr()).right;
                (*parent.as_ptr()).left = Some(node_c);
                (*node_c.as_ptr()).parent = Some(parent);
                (*node_b.as_ptr()).left = node_d;
                if let Some(n_d) = node_d {
                    (*n_d.as_ptr()).parent = Some(node_b);
                }
                (*node_c.as_ptr()).right = Some(node_b);
                (*node_b.as_ptr()).parent = Some(node_c);
                (*node_c.as_ptr()).left = Some(node_a);
                (*node_a.as_ptr()).parent = Some(node_c);
                (*node_a.as_ptr()).right = node_e;
                if let Some(n_e) = node_e {
                    (*n_e.as_ptr()).parent = Some(node_a);
                }
            }
        }

        /// 2.1.2.1 remove black X
        ///
        /// ```text
        ///              P            P
        ///             //           /
        ///            A            A
        ///           / \          //
        ///          B   X   =>   B
        ///
        /// ```
        unsafe fn remove_black_leaf_2_1_2_1_balancing(&mut self, node_x: &NonNull<Node<T>>) {
            unsafe {
                let node_a = (*node_x.as_ptr()).parent.unwrap();
                (*node_a.as_ptr()).is_red = false;
                if let Some(node_b) = (*node_a.as_ptr()).left {
                    (*node_b.as_ptr()).is_red = true;
                }
            }
        }

        /// 2.1.2.2 remove black X
        ///
        /// ```text
        ///             P            P
        ///            //           /
        ///            A     =>     B
        ///           / \          //\
        ///          X   B        A   D
        ///             / \        \
        ///            C   D        C
        /// ```
        unsafe fn remove_black_leaf_2_1_2_2_balancing(&mut self, node_x: &NonNull<Node<T>>) {
            unsafe {
                let node_a = (*node_x.as_ptr()).parent.unwrap();
                let node_b = (*node_a.as_ptr()).right.unwrap();
                let node_c = (*node_b.as_ptr()).left;
                let node_d = (*node_b.as_ptr()).right;
                let parent = (*node_a.as_ptr()).parent.unwrap();
                if let Some(left) = (*parent.as_ptr()).left {
                    if std::ptr::eq(node_a.as_ptr(), left.as_ptr()) {
                        (*parent.as_ptr()).left = Some(node_b);
                    } else {
                        (*parent.as_ptr()).right = Some(node_b);
                    }
                } else {
                    (*parent.as_ptr()).right = Some(node_b);
                }
                (*node_b.as_ptr()).parent = Some(parent);
                (*node_b.as_ptr()).left = Some(node_a);
                (*node_b.as_ptr()).right = node_d;
                if let Some(n_d) = node_d {
                    (*n_d.as_ptr()).parent = Some(node_b);
                }
                (*node_a.as_ptr()).parent = Some(node_b);
                (*node_a.as_ptr()).right = node_c;
                if let Some(n_c) = node_c {
                    (*n_c.as_ptr()).parent = Some(node_a);
                }
            }
        }

        /// 2.2.1 remove black X
        ///
        /// ```text
        ///            A               C
        ///          // \            //  \
        ///         B    X    =>    B     A
        ///          \               \   /
        ///           C               D E
        ///           //\
        ///          D   E
        /// ```
        unsafe fn remove_black_leaf_2_2_1_balancing(&mut self, node_x: &NonNull<Node<T>>) {
            unsafe {
                let n_a = node_x.as_ref().parent.unwrap();
                if n_a.as_ref().parent.is_some() {
                    let parent = (*n_a.as_ptr()).parent.unwrap();
                    let mut node_a_from_left = false;
                    if let Some(ref mut node_a) = (*parent.as_ptr()).left
                        && std::ptr::eq(node_a.as_ptr(), n_a.as_ptr())
                    {
                        node_a_from_left = true;
                    }
                    let node_a = if node_a_from_left {
                        (*parent.as_ptr()).left.unwrap()
                    } else {
                        (*parent.as_ptr()).right.unwrap()
                    };
                    let node_b = (*node_a.as_ptr()).left.unwrap();
                    let node_c = (*node_b.as_ptr()).right.unwrap();
                    let node_e = (*node_c.as_ptr()).right;
                    let node_d = (*node_c.as_ptr()).left.unwrap();
                    (*node_b.as_ptr()).right = Some(node_d);
                    (*node_b.as_ptr()).parent = Some(node_c);
                    (*node_d.as_ptr()).parent = Some(node_b);
                    (*node_a.as_ptr()).parent = Some(node_c);
                    (*node_a.as_ptr()).left = node_e;
                    if let Some(n_e) = node_e {
                        (*n_e.as_ptr()).parent = Some(node_a);
                    }
                    (*node_d.as_ptr()).is_red = false;
                    (*node_c.as_ptr()).left = Some(node_b);
                    (*node_c.as_ptr()).right = Some(node_a);
                    (*node_c.as_ptr()).parent = Some(parent);
                    if node_a_from_left {
                        (*parent.as_ptr()).left = Some(node_c);
                    } else {
                        (*parent.as_ptr()).right = Some(node_c);
                    }
                } else {
                    // node_a is root
                    if let Some(fixed_head) = self.fixed_head {
                        let node_a = (*fixed_head.as_ptr()).left.unwrap();
                        let node_b = (*node_a.as_ptr()).left.unwrap();
                        let node_c = (*node_b.as_ptr()).right.unwrap();
                        let node_e = (*node_c.as_ptr()).right;
                        let node_d = (*node_c.as_ptr()).left.unwrap();
                        (*node_b.as_ptr()).right = Some(node_d);
                        (*node_b.as_ptr()).parent = Some(node_c);
                        (*node_d.as_ptr()).parent = Some(node_b);
                        (*node_a.as_ptr()).parent = Some(node_c);
                        (*node_a.as_ptr()).left = node_e;
                        if let Some(n_e) = node_e {
                            (*n_e.as_ptr()).parent = Some(node_a);
                        }
                        (*node_d.as_ptr()).is_red = false;
                        (*node_c.as_ptr()).left = Some(node_b);
                        (*node_c.as_ptr()).right = Some(node_a);
                        (*node_c.as_ptr()).parent = None;
                        (*fixed_head.as_ptr()).left = Some(node_c);
                    }
                }
            }
        }

        /// 2.2.2 remove black X
        ///
        /// ```text
        ///    A            B
        ///  // \            \
        ///  B    X   =>       A
        ///  \               //
        ///   C             C
        /// ```
        unsafe fn remove_black_leaf_2_2_2_balancing(&mut self, node_x: &NonNull<Node<T>>) {
            unsafe {
                let n_a = node_x.as_ref().parent.unwrap();
                if n_a.as_ref().parent.is_some() {
                    let parent = (*n_a.as_ptr()).parent.unwrap();
                    let mut node_a_from_left = false;
                    if let Some(ref mut node_a) = (*parent.as_ptr()).left
                        && std::ptr::eq(node_a.as_ptr(), n_a.as_ptr())
                    {
                        node_a_from_left = true;
                    }
                    let node_a = if node_a_from_left {
                        (*parent.as_ptr()).left.unwrap()
                    } else {
                        (*parent.as_ptr()).right.unwrap()
                    };
                    let node_b = (*node_a.as_ptr()).left.unwrap();
                    (*node_b.as_ptr()).is_red = false;
                    (*node_b.as_ptr()).parent = Some(parent);
                    let node_c = (*node_b.as_ptr()).right.unwrap();
                    (*node_c.as_ptr()).is_red = true;
                    (*node_b.as_ptr()).right = Some(node_a);
                    (*node_a.as_ptr()).left = Some(node_c);
                    (*node_c.as_ptr()).parent = Some(node_a);
                    (*node_a.as_ptr()).parent = Some(node_b);
                    if node_a_from_left {
                        (*parent.as_ptr()).left = Some(node_b);
                    } else {
                        (*parent.as_ptr()).right = Some(node_b);
                    }
                } else {
                    // node_a is root
                    if let Some(fixed_head) = self.fixed_head {
                        let node_a = (*fixed_head.as_ptr()).left.unwrap();
                        let node_b = (*node_a.as_ptr()).left.unwrap();
                        (*node_b.as_ptr()).is_red = false;
                        (*node_b.as_ptr()).parent = None;
                        let node_c = (*node_b.as_ptr()).right.unwrap();
                        (*node_c.as_ptr()).is_red = true;
                        (*node_b.as_ptr()).right = Some(node_a);
                        (*node_a.as_ptr()).left = Some(node_c);
                        (*node_c.as_ptr()).parent = Some(node_a);
                        (*node_a.as_ptr()).parent = Some(node_b);
                        (*fixed_head.as_ptr()).left = Some(node_b);
                    }
                }
            }
        }

        /// 2.3.1.1 remove black X
        ///
        /// ```text
        ///      A           B
        ///     / \         / \
        ///    B   X  =>   D   A
        ///   // \            /
        ///  D    C          C
        /// ```
        unsafe fn remove_black_leaf_2_3_1_1_balancing(&mut self, node_x: &NonNull<Node<T>>) {
            unsafe {
                let node_a = (*node_x.as_ptr()).parent.unwrap();
                if let Some(parent) = (*node_a.as_ptr()).parent {
                    let node_b = (*node_a.as_ptr()).left.unwrap();
                    let node_c = (*node_b.as_ptr()).right;
                    let node_d = (*node_b.as_ptr()).left.unwrap();
                    (*node_d.as_ptr()).is_red = false;
                    let mut node_a_from_left = false;
                    if let Some(p_node_a) = (*parent.as_ptr()).left
                        && std::ptr::eq(p_node_a.as_ptr(), node_a.as_ptr())
                    {
                        node_a_from_left = true;
                    }
                    (*node_b.as_ptr()).parent = Some(parent);
                    (*node_b.as_ptr()).right = Some(node_a);
                    (*node_a.as_ptr()).parent = Some(node_b);
                    (*node_a.as_ptr()).left = node_c;
                    if let Some(n_c) = node_c {
                        (*n_c.as_ptr()).parent = Some(node_a);
                    }
                    if node_a_from_left {
                        (*parent.as_ptr()).left = Some(node_b);
                    } else {
                        (*parent.as_ptr()).right = Some(node_b);
                    }
                } else {
                    // node_a is root
                    if let Some(fixed_head) = self.fixed_head {
                        let node_a = (*fixed_head.as_ptr()).left.unwrap();
                        let node_b = (*node_a.as_ptr()).left.unwrap();
                        let node_c = (*node_b.as_ptr()).right;
                        let node_d = (*node_b.as_ptr()).left.unwrap();
                        (*node_d.as_ptr()).is_red = false;
                        let node_b = (*node_a.as_ptr()).left.unwrap();
                        (*node_b.as_ptr()).parent = None;
                        (*node_b.as_ptr()).right = Some(node_a);
                        (*node_a.as_ptr()).parent = Some(node_b);
                        (*node_a.as_ptr()).left = node_c;
                        if let Some(n_c) = node_c {
                            (*n_c.as_ptr()).parent = Some(node_a);
                        }
                        (*fixed_head.as_ptr()).left = Some(node_b);
                    }
                }
            }
        }

        /// 2.3.1.2 remove black X
        ///
        /// ```text
        ///
        ///      A            D
        ///     / \         /   \
        ///    X   B  =>   A     B
        ///       //        \   /
        ///       D          C E
        ///      / \
        ///     C   E
        /// ```
        unsafe fn remove_black_leaf_2_3_1_2_balancing(&mut self, node_x: &NonNull<Node<T>>) {
            unsafe {
                let node_a = (*node_x.as_ptr()).parent.unwrap();
                if let Some(parent) = (*node_a.as_ptr()).parent {
                    let node_b = (*node_a.as_ptr()).right.unwrap();
                    let node_d = (*node_b.as_ptr()).left.unwrap();
                    let node_c = (*node_d.as_ptr()).left;
                    let node_e = (*node_d.as_ptr()).right;
                    (*node_d.as_ptr()).is_red = false;
                    let mut node_a_from_left = false;
                    if let Some(p_node_a) = (*parent.as_ptr()).left
                        && std::ptr::eq(p_node_a.as_ptr(), node_a.as_ptr())
                    {
                        node_a_from_left = true;
                    }
                    (*node_d.as_ptr()).parent = Some(parent);
                    (*node_d.as_ptr()).left = Some(node_a);
                    (*node_d.as_ptr()).right = Some(node_b);
                    (*node_a.as_ptr()).parent = Some(node_d);
                    (*node_b.as_ptr()).parent = Some(node_d);
                    (*node_a.as_ptr()).right = node_c;
                    if let Some(n_c) = node_c {
                        (*n_c.as_ptr()).parent = Some(node_a);
                    }
                    (*node_b.as_ptr()).left = node_e;
                    if let Some(n_e) = node_e {
                        (*n_e.as_ptr()).parent = Some(node_b);
                    }
                    if node_a_from_left {
                        (*parent.as_ptr()).left = Some(node_d);
                    } else {
                        (*parent.as_ptr()).right = Some(node_d);
                    }
                } else {
                    // node_a is root
                    if let Some(fixed_head) = self.fixed_head {
                        let node_a = (*fixed_head.as_ptr()).left.unwrap();
                        let node_b = (*node_a.as_ptr()).right.unwrap();
                        let node_d = (*node_b.as_ptr()).left.unwrap();
                        let node_c = (*node_d.as_ptr()).left;
                        let node_e = (*node_d.as_ptr()).right;
                        (*node_d.as_ptr()).is_red = false;
                        (*node_d.as_ptr()).parent = None;
                        (*node_d.as_ptr()).left = Some(node_a);
                        (*node_d.as_ptr()).right = Some(node_b);
                        (*node_a.as_ptr()).parent = Some(node_d);
                        (*node_b.as_ptr()).parent = Some(node_d);
                        (*node_a.as_ptr()).right = node_c;
                        if let Some(n_c) = node_c {
                            (*n_c.as_ptr()).parent = Some(node_a);
                        }
                        (*node_b.as_ptr()).left = node_e;
                        if let Some(n_e) = node_e {
                            (*n_e.as_ptr()).parent = Some(node_b);
                        }
                        (*fixed_head.as_ptr()).left = Some(node_d);
                    }
                }
            }
        }

        /// 2.3.2.1 remove black X
        ///
        /// ```text
        ///            P           P
        ///            |           |
        ///            A           A
        ///           / \   =>    //   => next check node A
        ///          B   X       B
        ///
        /// ```
        unsafe fn remove_black_leaf_2_3_2_1_balancing(
            &mut self,
            node_x: &NonNull<Node<T>>,
        ) -> NonNull<Node<T>> {
            unsafe {
                let node_a = (*node_x.as_ptr()).parent.unwrap();
                let node_b = (*node_a.as_ptr()).left.unwrap();
                (*node_b.as_ptr()).is_red = true;
                node_a
            }
        }

        /// 2.3.2.2 remove black X
        ///
        /// ```text
        ///              A            B
        ///             / \   =>    // \    =>  next check node B
        ///            X   B       A    D
        ///               / \       \
        ///              C   D       C
        /// ```
        unsafe fn remove_black_leaf_2_3_2_2_balancing(
            &mut self,
            node_x: &NonNull<Node<T>>,
        ) -> NonNull<Node<T>> {
            unsafe {
                let node_a = (*node_x.as_ptr()).parent.unwrap();
                (*node_a.as_ptr()).is_red = true;
                if let Some(parent) = (*node_a.as_ptr()).parent {
                    let node_b = (*node_a.as_ptr()).right.unwrap();
                    let node_c = (*node_b.as_ptr()).left;
                    let node_d = (*node_b.as_ptr()).right;
                    let mut node_a_from_left = false;
                    if let Some(p_node_a) = (*parent.as_ptr()).left
                        && std::ptr::eq(p_node_a.as_ptr(), node_a.as_ptr())
                    {
                        node_a_from_left = true;
                    }
                    (*node_b.as_ptr()).parent = Some(parent);
                    (*node_a.as_ptr()).right = node_c;
                    if let Some(n_c) = node_c {
                        (*n_c.as_ptr()).parent = Some(node_a);
                    }
                    (*node_b.as_ptr()).right = node_d;
                    if let Some(n_d) = node_d {
                        (*n_d.as_ptr()).parent = Some(node_b);
                    }
                    (*node_b.as_ptr()).left = Some(node_a);
                    (*node_a.as_ptr()).parent = Some(node_b);
                    if node_a_from_left {
                        (*parent.as_ptr()).left = Some(node_b);
                    } else {
                        (*parent.as_ptr()).right = Some(node_b);
                    }
                    node_b
                } else {
                    // node_a is root
                    if let Some(fixed_head) = self.fixed_head {
                        let node_a = (*fixed_head.as_ptr()).left.unwrap();
                        (*node_a.as_ptr()).is_red = true;
                        let node_b = (*node_a.as_ptr()).right.unwrap();
                        let node_c = (*node_b.as_ptr()).left;
                        let node_d = (*node_b.as_ptr()).right;
                        (*node_b.as_ptr()).parent = None;
                        (*node_a.as_ptr()).right = node_c;
                        if let Some(n_c) = node_c {
                            (*n_c.as_ptr()).parent = Some(node_a);
                        }
                        (*node_b.as_ptr()).right = node_d;
                        if let Some(n_d) = node_d {
                            (*n_d.as_ptr()).parent = Some(node_b);
                        }
                        (*node_b.as_ptr()).left = Some(node_a);
                        (*node_a.as_ptr()).parent = Some(node_b);
                        (*fixed_head.as_ptr()).left = Some(node_b);
                    }
                    self.get_root().unwrap()
                }
            }
        }

        unsafe fn remove_node(&mut self, node: NonNull<Node<T>>) -> bool {
            unsafe {
                match self.operation_remove(&node) {
                    OperationRemove::RedLeaf => {
                        // option 1.0.0
                        //
                        // ```text
                        //
                        //  P
                        //  ||
                        //  X
                        //
                        // ```

                        self.remove_leaf(node)
                    }
                    OperationRemove::BlackLeaf => {
                        // option 2 black leaf
                        self.remove_black_leaf(node)
                    }
                    OperationRemove::NodeWithChildren => {
                        // option 4.0.0
                        // ```text
                        //        X
                        //     /      \
                        //    L        R
                        //   / \      / \
                        // ...  C    L
                        //          /
                        //         C
                        //        ...
                        //
                        // ```
                        /*
                            The node has two children.

                            We take the predecessor:
                            the maximal node of the left subtree.

                            We only change the values,
                            then we delete the predecessor as a regular node.
                        */

                        let predecessor = self.find_max(node.as_ref().left.unwrap());

                        std::mem::swap(
                            &mut (*node.as_ptr()).value,
                            &mut (*predecessor.as_ptr()).value,
                        );

                        self.remove_node(predecessor)
                    }
                    OperationRemove::BlackNodeWithRedLeaf => {
                        // option 3.0.0
                        // ```text
                        //  X
                        // //
                        // A
                        // ```
                        let red_left = (*node.as_ptr()).left.unwrap();
                        std::mem::swap(&mut (*node.as_ptr()).value, &mut (*red_left.as_ptr()).value);
                        self.remove_leaf(red_left)
                    }
                }
            }
        }

        unsafe fn find_max(&self, node: NonNull<Node<T>>) -> NonNull<Node<T>> {
            unsafe {
                if node.as_ref().right.is_some() {
                    self.find_max(node.as_ref().right.unwrap())
                } else {
                    node
                }
            }
        }

        unsafe fn find_min(&self, node: NonNull<Node<T>>) -> NonNull<Node<T>> {
            unsafe {
                if node.as_ref().left.is_some() {
                    self.find_min(node.as_ref().left.unwrap())
                } else {
                    node
                }
            }
        }

        unsafe fn remove_leaf(&mut self, node: NonNull<Node<T>>) -> bool {
            unsafe {
                if let Some(mut parent) = node.as_ref().parent {
                    if let Some(ref mut left) = parent.as_mut().left {
                        if std::ptr::eq(left.as_ptr(), node.as_ptr()) {
                            parent.as_mut().left = None;
                        } else {
                            parent.as_mut().right = None;
                        }
                    } else {
                        parent.as_mut().right = None;
                    }
                }
                let _ = Box::from_raw(node.as_ptr());
                true
            }
        }

        unsafe fn remove_tree(&mut self, node: Link<T>) {
            unsafe {
                if let Some(node) = node {
                    self.remove_tree(node.as_ref().left);
                    self.remove_tree(node.as_ref().right);
                    if self.remove_leaf(node) {
                        assert!(self.count > 0);
                        self.count -= 1;
                    }
                }
            }
        }

        /// Rotate left and Rotate right and Flip color
        ///
        /// ```text
        ///             |              ||
        ///             P              C
        ///           //  \          /   \
        ///          A     F        A     P
        ///         / \\      =>   / \   / \
        ///        B   C          B   E D   F
        ///            / \
        ///           E   D
        /// ```
        unsafe fn rotate_left_right_flip_color(&mut self, node_a: NonNull<Node<T>>) -> Link<T> {
            unsafe {
                let node_p = (*node_a.as_ptr()).parent.unwrap();
                if let Some(parent) = (*node_p.as_ptr()).parent {
                    let mut node_p_from_left = false;
                    if let Some(p_node_p) = (*parent.as_ptr()).left
                        && std::ptr::eq(p_node_p.as_ptr(), node_p.as_ptr())
                    {
                        node_p_from_left = true;
                    }
                    let node_p = if node_p_from_left {
                        (*parent.as_ptr()).left.unwrap()
                    } else {
                        (*parent.as_ptr()).right.unwrap()
                    };
                    (*node_a.as_ptr()).is_red = false;
                    let node_c = (*node_a.as_ptr()).right.unwrap();
                    (*node_c.as_ptr()).is_red = false;
                    let node_e = (*node_c.as_ptr()).left;
                    let node_d = (*node_c.as_ptr()).right;
                    (*node_c.as_ptr()).is_red = true;
                    (*node_c.as_ptr()).parent = Some(parent);
                    (*node_c.as_ptr()).left = Some(node_a);
                    (*node_a.as_ptr()).parent = Some(node_c);
                    (*node_c.as_ptr()).right = Some(node_p);
                    (*node_p.as_ptr()).parent = Some(node_c);
                    (*node_p.as_ptr()).left = node_d;
                    if let Some(n_d) = node_d {
                        (*n_d.as_ptr()).parent = Some(node_p);
                    }
                    (*node_a.as_ptr()).right = node_e;
                    if let Some(n_e) = node_e {
                        (*n_e.as_ptr()).parent = Some(node_a);
                    }
                    if node_p_from_left {
                        (*parent.as_ptr()).left = Some(node_c);
                    } else {
                        (*parent.as_ptr()).right = Some(node_c);
                    }
                    Some(parent)
                } else {
                    let fixed_head = self.fixed_head.unwrap();
                    let node_p = (*fixed_head.as_ptr()).left.unwrap();

                    let node_a = (*node_p.as_ptr()).left.unwrap();
                    (*node_a.as_ptr()).is_red = false;
                    let node_c = (*node_a.as_ptr()).right.unwrap();
                    (*node_c.as_ptr()).is_red = false;
                    let node_e = (*node_c.as_ptr()).left;
                    let node_d = (*node_c.as_ptr()).right;
                    (*node_c.as_ptr()).is_red = false;
                    (*node_c.as_ptr()).parent = None;
                    (*node_c.as_ptr()).left = Some(node_a);
                    (*node_a.as_ptr()).parent = Some(node_c);
                    (*node_c.as_ptr()).right = Some(node_p);
                    (*node_p.as_ptr()).parent = Some(node_c);
                    (*node_p.as_ptr()).left = node_d;
                    if let Some(n_d) = node_d {
                        (*n_d.as_ptr()).parent = Some(node_p);
                    }
                    (*node_a.as_ptr()).right = node_e;
                    if let Some(n_e) = node_e {
                        (*n_e.as_ptr()).parent = Some(node_a);
                    }
                    (*fixed_head.as_ptr()).left = Some(node_c);
                    (*fixed_head.as_ptr()).left
                }
            }
        }

        /// Rotate left without parent
        /// A is root
        ///
        /// ```text
        ///             A                  C
        ///            / \\               //\
        ///           B    C     =>      A   D
        ///               / \           / \
        ///              E   D         B   E
        ///
        /// ```
        ///
        /// Rotate left  with parent
        ///
        /// ```text
        ///             P                  P
        ///             |                  |
        ///             A                  C
        ///            / \\               //\
        ///           B    C     =>      A   D
        ///               / \           / \
        ///              E   D         B   E
        ///
        /// ```
        unsafe fn rotate_left(&mut self, node_a: NonNull<Node<T>>) -> Link<T> {
            unsafe {
                if let Some(parent) = (*node_a.as_ptr()).parent {
                    let mut node_a_from_left = false;
                    if let Some(p_node_a) = (*parent.as_ptr()).left
                        && std::ptr::eq(p_node_a.as_ptr(), node_a.as_ptr())
                    {
                        node_a_from_left = true;
                    }
                    let node_a = if node_a_from_left {
                        (*parent.as_ptr()).left.unwrap()
                    } else {
                        (*parent.as_ptr()).right.unwrap()
                    };
                    let node_c = (*node_a.as_ptr()).right.unwrap();
                    (*node_c.as_ptr()).is_red = (*node_a.as_ptr()).is_red;
                    (*node_a.as_ptr()).is_red = true;
                    (*node_c.as_ptr()).parent = Some(parent);
                    if node_c.as_ref().left.is_some() {
                        let mut node_e = (*node_c.as_ptr()).left;
                        if let Some(e) = &mut node_e {
                            (*e.as_ptr()).parent = Some(node_a);
                        }
                        (*node_a.as_ptr()).right = node_e;
                    } else {
                        (*node_a.as_ptr()).right = None;
                    }
                    (*node_c.as_ptr()).left = Some(node_a);
                    (*node_a.as_ptr()).parent = Some(node_c);
                    if node_a_from_left {
                        (*parent.as_ptr()).left = Some(node_c);
                        (*parent.as_ptr()).left
                    } else {
                        (*parent.as_ptr()).right = Some(node_c);
                        (*parent.as_ptr()).right
                    }
                } else {
                    let fixed_head = self.fixed_head.unwrap();
                    let node_a = (*fixed_head.as_ptr()).left.unwrap();
                    let node_c = (*node_a.as_ptr()).right.unwrap();
                    (*node_c.as_ptr()).is_red = (*node_a.as_ptr()).is_red;
                    (*node_a.as_ptr()).is_red = true;
                    if node_c.as_ref().left.is_some() {
                        let mut node_e = (*node_c.as_ptr()).left;
                        if let Some(e) = &mut node_e {
                            (*e.as_ptr()).parent = Some(node_a);
                        }
                        (*node_a.as_ptr()).right = node_e;
                    } else {
                        (*node_a.as_ptr()).right = None;
                    }
                    (*node_c.as_ptr()).left = Some(node_a);
                    (*node_a.as_ptr()).parent = Some(node_c);
                    (*node_c.as_ptr()).parent = None;
                    (*fixed_head.as_ptr()).left = Some(node_c);
                    (*fixed_head.as_ptr()).left
                }
            }
        }

        /// Rotate right without parent
        /// A is root
        ///
        /// ```text
        ///              A               B
        ///            // \             / \\
        ///            B   C     =>    E    A
        ///          // \                  / \
        ///         E    D                D   C
        /// ```
        ///
        /// Rotate right with parent
        ///
        /// ```text
        ///                P               P
        ///                |               |
        ///                A               B
        ///              // \             / \\
        ///              B   C     =>    E    A
        ///            // \                  / \
        ///           E    D                D   C
        ///
        /// ```
        unsafe fn rotate_right(&mut self, node_a: NonNull<Node<T>>) -> Link<T> {
            unsafe {
                if let Some(parent) = (*node_a.as_ptr()).parent {
                    let mut node_a_from_left = false;
                    if let Some(p_node_a) = (*parent.as_ptr()).left
                        && std::ptr::eq(p_node_a.as_ptr(), node_a.as_ptr())
                    {
                        node_a_from_left = true;
                    }
                    let node_a = if node_a_from_left {
                        (*parent.as_ptr()).left.unwrap()
                    } else {
                        (*parent.as_ptr()).right.unwrap()
                    };
                    let node_b = (*node_a.as_ptr()).left.unwrap();
                    (*node_b.as_ptr()).parent = Some(parent);
                    (*node_b.as_ptr()).is_red = (*node_a.as_ptr()).is_red;
                    (*node_a.as_ptr()).is_red = true;
                    if node_b.as_ref().right.is_some() {
                        let mut node_d = (*node_b.as_ptr()).right;
                        if let Some(d) = &mut node_d {
                            (*d.as_ptr()).parent = Some(node_a);
                        }
                        (*node_a.as_ptr()).left = node_d;
                    } else {
                        (*node_a.as_ptr()).left = None;
                    }
                    (*node_b.as_ptr()).right = Some(node_a);
                    (*node_a.as_ptr()).parent = Some(node_b);
                    if node_a_from_left {
                        (*parent.as_ptr()).left = Some(node_b);
                        (*parent.as_ptr()).left
                    } else {
                        (*parent.as_ptr()).right = Some(node_b);
                        (*parent.as_ptr()).right
                    }
                } else {
                    let fixed_head = self.fixed_head.unwrap();
                    let node_a = (*fixed_head.as_ptr()).left.unwrap();
                    let node_b = (*node_a.as_ptr()).left.unwrap();
                    (*node_b.as_ptr()).is_red = (*node_a.as_ptr()).is_red;
                    (*node_a.as_ptr()).is_red = true;
                    if node_b.as_ref().right.is_some() {
                        let mut node_d = (*node_b.as_ptr()).right;
                        if let Some(d) = &mut node_d {
                            (*d.as_ptr()).parent = Some(node_a);
                        }
                        (*node_a.as_ptr()).left = node_d;
                    } else {
                        (*node_a.as_ptr()).left = None;
                    }
                    (*node_b.as_ptr()).right = Some(node_a);
                    (*node_a.as_ptr()).parent = Some(node_b);
                    (*node_b.as_ptr()).parent = None;
                    (*fixed_head.as_ptr()).left = Some(node_b);
                    (*fixed_head.as_ptr()).left
                }
            }
        }

        /// Flip color
        ///
        /// ```text
        ///             |          ||
        ///             A    =>    A
        ///           // \\       / \
        ///          B    C      B   C
        ///
        /// ```
        unsafe fn flip_colors(&mut self, mut node: NonNull<Node<T>>) {
            unsafe {
                if node.as_ref().left.is_some() && node.as_ref().right.is_some() {
                    if let Some(ref mut left) = node.as_mut().left {
                        left.as_mut().is_red = false;
                    }
                    if let Some(ref mut right) = node.as_mut().right {
                        right.as_mut().is_red = false;
                    }
                    node.as_mut().is_red = true;

                    if (*node.as_ptr()).parent.is_none() {
                        node.as_mut().is_red = false;
                    }
                }
            }
        }

        unsafe fn check_put_balancing(&mut self, node: NonNull<Node<T>>) -> OperationPut {
            unsafe {
                if node.as_ref().right.is_some() {
                    let r = node.as_ref().right.unwrap();
                    if node.as_ref().left.is_some() && !node.as_ref().is_red {
                        let l = node.as_ref().left.unwrap();
                        if l.as_ref().is_red && r.as_ref().is_red {
                            return OperationPut::FlipColors;
                        }
                    }
                    if r.as_ref().is_red {
                        return OperationPut::Left;
                    }
                }
                if node.as_ref().is_red && node.as_ref().left.is_some() {
                    let l = node.as_ref().left.unwrap();
                    if l.as_ref().is_red {
                        return OperationPut::Right;
                    }
                }
                OperationPut::Nothing
            }
        }

        unsafe fn put_balancing(&mut self, next: NonNull<Node<T>>) {
            unsafe {
                let mut next = next;
                loop {
                    match self.check_put_balancing(next) {
                        OperationPut::Left => {
                            if (*next.as_ptr()).is_red {
                                if let Some(n) = self.rotate_left_right_flip_color(next) {
                                    next = n;
                                }
                            } else {
                                if let Some(n) = self.rotate_left(next) {
                                    next = n;
                                }
                            }
                        }
                        OperationPut::Right => {
                            if (*next.as_ptr()).parent.is_some() {
                                let node_a = (*next.as_ptr()).parent.unwrap();
                                if let Some(n) = self.rotate_right(node_a) {
                                    next = n;
                                }
                            }
                        }
                        OperationPut::FlipColors => {
                            self.flip_colors(next);
                            if (*next.as_ptr()).parent.is_some() {
                                next = (*next.as_ptr()).parent.unwrap();
                            } else {
                                break;
                            }
                        }
                        OperationPut::Nothing => {
                            break;
                        }
                    }
                }
            }
        }

        unsafe fn find_put_parent_candidate(&mut self, parent: Link<T>, elem: &T) -> Link<T> {
            unsafe {
                if let Some(parent) = parent {
                    match elem.cmp(&parent.as_ref().value) {
                        Ordering::Equal => None,
                        Ordering::Less => {
                            if (*parent.as_ptr()).left.is_some() {
                                self.find_put_parent_candidate((*parent.as_ptr()).left, elem)
                            } else {
                                Some(parent)
                            }
                        }
                        Ordering::Greater => {
                            if (*parent.as_ptr()).right.is_some() {
                                self.find_put_parent_candidate((*parent.as_ptr()).right, elem)
                            } else {
                                Some(parent)
                            }
                        }
                    }
                } else {
                    parent
                }
            }
        }

        unsafe fn attach_node(&mut self, parent: NonNull<Node<T>>, elem: T) -> bool {
            unsafe {
                match elem.cmp(&parent.as_ref().value) {
                    Ordering::Equal => false,
                    Ordering::Less => {
                        (*parent.as_ptr()).left = Node::new_red(elem, parent);
                        true
                    }
                    Ordering::Greater => {
                        (*parent.as_ptr()).right = Node::new_red(elem, parent);
                        true
                    }
                }
            }
        }

        /// Returns the default iterator over the tree.
        ///
        /// The default traversal is in-order (`LNR`), so values are yielded in
        /// ascending order.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([3, 1, 2]);
        ///
        /// let values: Vec<i32> = tree.iter().copied().collect();
        ///
        /// assert_eq!(values, vec![1, 2, 3]);
        /// ```
        pub fn iter(&self) -> IterInOrder<'_, T> {
            self.iter_inorder()
        }

        /// Returns an in-order (`LNR`) iterator.
        ///
        /// Values are yielded in ascending order.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([3, 1, 2]);
        ///
        /// assert_eq!(
        ///     tree.iter_inorder().copied().collect::<Vec<_>>(),
        ///     vec![1, 2, 3]
        /// );
        /// ```
        pub fn iter_inorder(&self) -> IterInOrder<'_, T> {
            unsafe { IterInOrder::new(leftmost_child_in_order(self.get_root()), self.count) }
        }

        /// Returns a reverse in-order (`RNL`) iterator.
        ///
        /// Values are yielded in descending order.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([3, 1, 2]);
        ///
        /// assert_eq!(
        ///     tree.iter_reverse_inorder().copied().collect::<Vec<_>>(),
        ///     vec![3, 2, 1]
        /// );
        /// ```
        pub fn iter_reverse_inorder(&self) -> IterReverseInOrder<'_, T> {
            unsafe {
                IterReverseInOrder::new(
                    rightmost_child_reverse_in_order(self.get_root()),
                    self.count,
                )
            }
        }

        /// Returns a pre-order (`NLR`) iterator.
        ///
        /// The current node is visited before its left and right subtrees.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([4, 2, 6, 1, 3, 5, 7]);
        ///
        /// let values: Vec<i32> = tree.iter_preorder().copied().collect();
        ///
        /// assert_eq!(values.len(), tree.len());
        /// ```
        pub fn iter_preorder(&self) -> IterPreOrder<'_, T> {
            IterPreOrder::new(self.get_root(), self.count)
        }

        /// Returns a post-order (`LRN`) iterator.
        ///
        /// The left and right subtrees are visited before the current node.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([4, 2, 6, 1, 3, 5, 7]);
        ///
        /// let values: Vec<i32> = tree.iter_postorder().copied().collect();
        ///
        /// assert_eq!(values.len(), tree.len());
        /// ```
        pub fn iter_postorder(&self) -> IterPostOrder<'_, T> {
            unsafe {
                let first = self.get_root().map(|root| leaf_post_order(root));
                IterPostOrder::new(first, self.count)
            }
        }

        /// Returns all values in level-order traversal.
        ///
        /// Nodes are visited level by level, starting from the root.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([4, 2, 6, 1, 3, 5, 7]);
        ///
        /// let values = tree.iter_level_order();
        ///
        /// assert_eq!(values.len(), tree.len());
        /// ```
        pub fn iter_level_order(&self) -> Vec<&T> {
            let mut ret: Vec<&T> = vec![];
            if let Some(root) = self.get_root() {
                iter_level_order_impl(root, &mut ret);
            }
            ret
        }
    }

    impl<'a, T: Ord + Default> std::iter::IntoIterator for &'a RedBlackTree<T> {
        type IntoIter = IterInOrder<'a, T>;
        type Item = &'a T;

        fn into_iter(self) -> Self::IntoIter {
            self.iter()
        }
    }

    impl<T: Ord + Default> Drop for RedBlackTree<T> {
        fn drop(&mut self) {
            unsafe {
                if let Some(fixed_head) = self.fixed_head {
                    self.remove_tree((*fixed_head.as_ptr()).left);
                    let _ = Box::from_raw(fixed_head.as_ptr());
                }
                self.fixed_head = None;
            }
        }
    }

    fn find_node<T: Ord>(fromnode: Link<T>, value: &T) -> Link<T> {
        unsafe {
            if let Some(fromnode) = fromnode {
                match value.cmp(&(*fromnode.as_ptr()).value) {
                    Ordering::Equal => Some(fromnode),
                    Ordering::Less => find_node((*fromnode.as_ptr()).left, value),
                    Ordering::Greater => find_node((*fromnode.as_ptr()).right, value),
                }
            } else {
                fromnode
            }
        }
    }

    fn helper_display_tree<T: Display>(node: NonNull<Node<T>>) -> String {
        unsafe {
            let mut s: String = "".into();
            let color = if (*node.as_ptr()).is_red {
                "[color=\"red\"]"
            } else {
                "[color=\"black\"]"
            };

            if let Some(left) = (*node.as_ptr()).left {
                s.push_str(&format!(
                    "\t{n1}->{n2} {color1}; {n1} {color1}; {n2} {color2};\n",
                    n1 = (*node.as_ptr()).value,
                    n2 = (*left.as_ptr()).value,
                    color1 = color,
                    color2 = if (*left.as_ptr()).is_red {
                        "[color=\"red\"]"
                    } else {
                        "[color=\"black\"]"
                    },
                ));
                s.push_str(&helper_display_tree(left));
            } else if (*node.as_ptr()).right.is_some() {
                s.push_str(&format!(
                    "\t{n1}->node_null_{n1} [color=\"grey\"]; {n1} {color1};\n",
                    n1 = (*node.as_ptr()).value,
                    color1 = color
                ));
                s.push_str(&format!(
                    "\tnode_null_{n1}[label=\"null\"]\n",
                    n1 = (*node.as_ptr()).value
                ));
            }

            if let Some(right) = (*node.as_ptr()).right {
                s.push_str(&format!(
                    "\t{n1}->{n2} {color1}; {n1} {color1}; {n2} {color2};\n",
                    n1 = (*node.as_ptr()).value,
                    n2 = (*right.as_ptr()).value,
                    color2 = if (*right.as_ptr()).is_red {
                        "[color=\"red\"]"
                    } else {
                        "[color=\"black\"]"
                    },
                    color1 = color
                ));
                s.push_str(&helper_display_tree(right));
            } else {
                s.push_str(&format!(
                    "\t{n1}->node_null_{n1} [color=\"grey\"]; {n1} {color1};\n",
                    n1 = (*node.as_ptr()).value,
                    color1 = color
                ));
                s.push_str(&format!(
                    "\tnode_null_{}[label=\"null\"]\n",
                    (*node.as_ptr()).value
                ));
            }
            s
        }
    }

    impl<T: Ord + Default> Default for RedBlackTree<T> {
        fn default() -> Self {
            Self::new()
        }
    }

    impl<T: Ord + Default + Clone> Clone for RedBlackTree<T> {
        fn clone(&self) -> Self {
            let mut new_list = Self::new();
            for value in self {
                new_list.insert(value.clone());
            }
            new_list
        }
    }

    impl<T: Ord + Default> Extend<T> for RedBlackTree<T> {
        fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
            for value in iter {
                self.insert(value);
            }
        }
    }

    impl<T: Ord + Default> FromIterator<T> for RedBlackTree<T> {
        fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
            let mut list = Self::new();
            list.extend(iter);
            list
        }
    }

    impl<T: Ord + Default + Debug> Debug for RedBlackTree<T> {
        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
            f.debug_list().entries(self).finish()
        }
    }

    impl<T: Ord + Default> PartialEq for RedBlackTree<T> {
        fn eq(&self, other: &Self) -> bool {
            self.len() == other.len() && self.iter_inorder().eq(other.iter_inorder())
        }
    }

    impl<T: Ord + Default> Eq for RedBlackTree<T> {}

    impl<T: Ord + Default> PartialOrd for RedBlackTree<T> {
        fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
            Some(self.cmp(other))
        }
    }

    impl<T: Ord + Default> Ord for RedBlackTree<T> {
        fn cmp(&self, other: &Self) -> Ordering {
            self.iter_inorder().cmp(other.iter_inorder())
        }
    }

    impl<T: Ord + Default + std::hash::Hash> std::hash::Hash for RedBlackTree<T> {
        fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
            self.len().hash(state);
            for item in self {
                item.hash(state);
            }
        }
    }
}

3. Диапазоны [min, max] (range queries)

Сложность работы алгоритма поиска результатов диапазона: , где:

  • n — количество элементов в дереве
  • k — количество элементов в результате

RedBlackTree особенно полезен, когда нужно быстро получить не одно значение, а все значения из диапазона:

  • все цены от 100 до 500
  • все timestamp за последний час
  • все ID от 1000 до 2000
fn main() {
    let mut prices = RedBlackTree::new();

    // Добавляем цены.
    for price in [220, 95, 310, 150, 260, 120, 180] {
        prices.insert(price);
    }

    println!("Все цены:");
    for price in prices.iter() {
        println!("{price}");
    }

    println!("\nЦены от 150 до 260:");
    for price in prices.range(&150, &260) {
        println!("{price}");
    }
}














/// -------------------------------------------
/// Implementation RBT
/// -------------------------------------------


pub use tree::RedBlackTree;
pub use iter::{IterInOrder, Range};
pub use iter::IterPreOrder;
pub use iter::IterReverseInOrder;
pub use iter::IterPostOrder;
 
pub mod iter{
    use std::ptr::NonNull;

    use crate::node::{Link, Node};

    ///```text
    ///
    ///            4
    ///          /   \
    ///         2     9
    ///        / \   //\
    ///       1   3  7   10
    ///             / \
    ///            6   8
    ///```
    ///    Depth-First Search / Pre-order (NLR):     4, 2, 1, 3, 9, 7, 6, 8, 10
    ///    Depth-First Search / In-order (LNR):      1, 2, 3, 4, 6, 7, 8, 9, 10
    ///    Depth-First Search / Post-order (LRN):    1, 3, 2, 6, 8, 7, 10, 9, 4
    ///    Breadth-First Search / Level-order:       4, 2, 9, 1, 3, 7, 10, 6, 8 
    pub use dfs_in_order::{IterInOrder, Range};

    pub(crate) use dfs_in_order::{leftmost_child_in_order, successor_of_node_in_order};

    mod dfs_in_order {
        use super::{Link, Node, NonNull};
        use std::iter::FusedIterator;
        use std::marker::PhantomData;

        /// Returns the next node in an in-order (`LNR`) traversal.
        ///
        /// # Safety
        ///
        /// `node` must point to a live node that belongs to the current tree, and
        /// all parent/child links reachable from it must be valid.
        pub unsafe fn successor_of_node_in_order<T>(node: NonNull<Node<T>>) -> Link<T> {
            unsafe {
                if node.as_ref().right.is_some() {
                    // If a right subtree exists, the successor is its leftmost node.
                    leftmost_child_in_order(node.as_ref().right)
                } else {
                    // Otherwise, walk up through parent links until the current
                    // node is found in a left subtree.
                    parent_with_left(node)
                }
            }
        }

        /// Returns the leftmost node reachable from `node`.
        ///
        /// Returns `None` when `node` is `None`.
        ///
        /// # Safety
        ///
        /// Every pointer reachable through `left` links must refer to a live node.
        pub unsafe fn leftmost_child_in_order<T>(node: Link<T>) -> Link<T> {
            unsafe {
                if let Some(node) = node {
                    if node.as_ref().left.is_none() {
                        Some(node)
                    } else {
                        leftmost_child_in_order(node.as_ref().left)
                    }
                } else {
                    node
                }
            }
        }

        /// Walks up the parent chain until an ancestor is reached from its left child.
        ///
        /// # Safety
        ///
        /// `node` and all parent links traversed by this function must be valid.
        unsafe fn parent_with_left<T>(node: NonNull<Node<T>>) -> Link<T> {
            unsafe {
                let parent = node.as_ref().parent;
                if let Some(parent) = parent
                    && let Some(left) = parent.as_ref().left
                {
                    if std::ptr::eq(left.as_ptr(), node.as_ptr()) {
                        return Some(parent);
                    }
                    return parent_with_left(parent);
                }
                // No parent means that the root has been reached.
                None
            }
        }

        /// Iterator over a tree in in-order (`Left -> Node -> Right`, or `LNR`).
        ///
        /// For a binary search tree, this traversal yields values in ascending order.
        pub struct IterInOrder<'a, T> {
            current_node: Link<T>,
            count: usize,
            elem: Option<&'a T>,
            _boo: PhantomData<&'a T>,
        }

        impl<'a, T> IterInOrder<'a, T> {
            /// Creates an in-order iterator starting at `node`.
            pub(crate) fn new(node: Link<T>, count: usize) -> Self {
                Self {
                    current_node: node,
                    count,
                    elem: None,
                    _boo: PhantomData,
                }
            }
        }

        impl<'a, T> Iterator for IterInOrder<'a, T> {
            type Item = &'a T;

            fn next(&mut self) -> Option<Self::Item> {
                if self.count > 0 {
                    self.count -= 1;
                    if let Some(node) = self.current_node {
                        unsafe {
                            self.elem = Some(&node.as_ref().value);
                            self.current_node = successor_of_node_in_order(node);
                        }
                    } else {
                        self.elem = None;
                    }
                } else {
                    self.elem = None;
                }
                self.elem
            }

            fn size_hint(&self) -> (usize, Option<usize>) {
                (self.count, Some(self.count))
            }
        }

        impl<'a, T> ExactSizeIterator for IterInOrder<'a, T> {
            fn len(&self) -> usize {
                self.count
            }
        }

        impl<'a, T> FusedIterator for IterInOrder<'a, T> {}

        /// A lazy iterator over an inclusive range of values in a [`crate::RedBlackTree`].
        ///
        /// `Range` is created by [`crate::RedBlackTree::range`]. It yields references to
        /// values in ascending order, starting from the first value greater than or
        /// equal to the lower bound and stopping after the upper bound.
        ///
        /// The iterator does not allocate an intermediate collection. Values are
        /// produced one at a time as the iterator advances.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([1, 3, 5, 7, 9, 11]);
        ///
        /// let values: Vec<_> = tree
        ///     .range(&3, &9)
        ///     .copied()
        ///     .collect();
        ///
        /// assert_eq!(values, vec![3, 5, 7, 9]);
        /// ```
        ///
        /// The iterator can be combined with standard iterator adapters:
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend(1..=100);
        ///
        /// let values: Vec<_> = tree
        ///     .range(&20, &80)
        ///     .take(3)
        ///     .copied()
        ///     .collect();
        ///
        /// assert_eq!(values, vec![20, 21, 22]);
        /// ```
        pub struct Range<'a, T> {
            current_node: Link<T>,
            end_node: Link<T>,
            _marker: PhantomData<&'a T>,
        }

        impl<'a, T: Ord> Range<'a, T> {
            pub(crate) fn new(root: Link<T>, min: &T, max: &T) -> Self {
                if min > max {
                    return Self {
                        current_node: None,
                        end_node: None,
                        _marker: PhantomData,
                    };
                }

                unsafe {
                    let mut current = root;
                    let mut start: Link<T> = None;

                    // First node >= min.
                    while let Some(node) = current {
                        match node.as_ref().value.cmp(min) {
                            std::cmp::Ordering::Less => {
                                current = node.as_ref().right;
                            }

                            std::cmp::Ordering::Equal => {
                                start = Some(node);
                                break;
                            }

                            std::cmp::Ordering::Greater => {
                                start = Some(node);
                                current = node.as_ref().left;
                            }
                        }
                    }

                    current = root;

                    let mut end: Link<T> = None;

                    // First node > max.
                    while let Some(node) = current {
                        match node.as_ref().value.cmp(max) {
                            std::cmp::Ordering::Less | std::cmp::Ordering::Equal => {
                                current = node.as_ref().right;
                            }

                            std::cmp::Ordering::Greater => {
                                end = Some(node);
                                current = node.as_ref().left;
                            }
                        }
                    }

                    Self {
                        current_node: start,
                        end_node: end,
                        _marker: PhantomData,
                    }
                }
            }
        }

        impl<'a, T> Iterator for Range<'a, T> {
            type Item = &'a T;

            fn next(&mut self) -> Option<Self::Item> {
                let node = self.current_node?;

                if self.end_node == Some(node) {
                    self.current_node = None;
                    return None;
                }

                unsafe {
                    let value = &node.as_ref().value;

                    self.current_node = successor_of_node_in_order(node);

                    Some(value)
                }
            }
        }
    }

    pub use dfs_reverse_in_order::IterReverseInOrder;

    pub(crate) use dfs_reverse_in_order::{
        rightmost_child_reverse_in_order, successor_of_node_reverse_in_order,
    };

    mod dfs_reverse_in_order {
        use super::{Link, Node, NonNull};
        use std::marker::PhantomData;

        /// Returns the next node in reverse in-order (`Right -> Node -> Left`, or `RNL`).
        ///
        /// # Safety
        ///
        /// `node` must point to a live node that belongs to the current tree, and
        /// all parent/child links reachable from it must be valid.
        pub unsafe fn successor_of_node_reverse_in_order<T>(node: NonNull<Node<T>>) -> Link<T> {
            unsafe {
                if node.as_ref().left.is_some() {
                    // After the current node, descend into the left subtree and
                    // choose its rightmost node.
                    rightmost_child_reverse_in_order(node.as_ref().left)
                } else {
                    // Without a left subtree, walk upward until reaching an
                    // ancestor from its right subtree.
                    parent_with_right(node)
                }
            }
        }

        /// Returns the rightmost node reachable from `node`.
        ///
        /// Returns `None` when `node` is `None`.
        ///
        /// # Safety
        ///
        /// Every pointer reachable through `right` links must refer to a live node.
        pub unsafe fn rightmost_child_reverse_in_order<T>(node: Link<T>) -> Link<T> {
            unsafe {
                if let Some(node) = node {
                    if node.as_ref().right.is_none() {
                        Some(node)
                    } else {
                        rightmost_child_reverse_in_order(node.as_ref().right)
                    }
                } else {
                    None
                }
            }
        }

        /// Walks up the parent chain until an ancestor is reached from its right child.
        ///
        /// # Safety
        ///
        /// `node` and all parent links traversed by this function must be valid.
        unsafe fn parent_with_right<T>(node: NonNull<Node<T>>) -> Link<T> {
            unsafe {
                let parent = node.as_ref().parent;

                if let Some(parent) = parent
                    && let Some(right) = parent.as_ref().right
                {
                    if std::ptr::eq(right.as_ptr(), node.as_ptr()) {
                        return Some(parent);
                    }

                    return parent_with_right(parent);
                }

                None
            }
        }

        /// Iterator over a tree in reverse in-order (`Right -> Node -> Left`, or `RNL`).
        ///
        /// For a binary search tree, this traversal yields values in descending order.
        pub struct IterReverseInOrder<'a, T> {
            current_node: Link<T>,
            count: usize,
            elem: Option<&'a T>,
            _boo: PhantomData<&'a T>,
        }

        impl<'a, T> IterReverseInOrder<'a, T> {
            /// Creates a reverse in-order iterator starting at `node`.
            pub(crate) fn new(node: Link<T>, count: usize) -> Self {
                Self {
                    current_node: node,
                    count,
                    elem: None,
                    _boo: PhantomData,
                }
            }
        }

        impl<'a, T> Iterator for IterReverseInOrder<'a, T> {
            type Item = &'a T;

            fn next(&mut self) -> Option<Self::Item> {
                if self.count > 0 {
                    self.count -= 1;

                    if let Some(node) = self.current_node {
                        unsafe {
                            self.elem = Some(&node.as_ref().value);
                            self.current_node = successor_of_node_reverse_in_order(node);
                        }
                    } else {
                        self.elem = None;
                    }
                } else {
                    self.elem = None;
                }

                self.elem
            }

            fn size_hint(&self) -> (usize, Option<usize>) {
                (self.count, Some(self.count))
            }
        }
    }

    pub use dfs_pre_order::IterPreOrder;

    pub(crate) use dfs_pre_order::successor_of_node_pre_order;

    mod dfs_pre_order {
        use super::{Link, Node, NonNull};
        use std::marker::PhantomData;

        /// Returns the next node in a pre-order (`Node -> Left -> Right`, or `NLR`) traversal.
        ///
        /// # Safety
        ///
        /// `node` must point to a live node in the current tree and all traversed
        /// links must be valid.
        pub unsafe fn successor_of_node_pre_order<T>(node: NonNull<Node<T>>) -> Link<T> {
            unsafe {
                if let Some(node) = node.as_ref().left {
                    Some(node)
                } else if let Some(node) = node.as_ref().right {
                    Some(node)
                } else {
                    right_with_parent(node)
                }
            }
        }

        /// Finds the next right subtree by walking through parent links.
        ///
        /// # Safety
        ///
        /// `node` and all parent links traversed by this function must be valid.
        unsafe fn right_with_parent<T>(node: NonNull<Node<T>>) -> Link<T> {
            unsafe {
                if let Some(parent) = node.as_ref().parent {
                    next_right(Some(parent), node)
                } else {
                    None
                }
            }
        }

        /// Searches ancestors for the next unvisited right child.
        ///
        /// # Safety
        ///
        /// `child`, `node`, and all links traversed by this function must be valid.
        unsafe fn next_right<T>(node: Link<T>, child: NonNull<Node<T>>) -> Link<T> {
            unsafe {
                if let Some(n) = node {
                    if let Some(right) = n.as_ref().right {
                        if std::ptr::eq(right.as_ptr(), child.as_ptr()) {
                            next_right(n.as_ref().parent, n)
                        } else {
                            Some(right)
                        }
                    } else {
                        next_right(n.as_ref().parent, n)
                    }
                } else {
                    None
                }
            }
        }

        /// Iterator over a tree in pre-order (`Node -> Left -> Right`, or `NLR`).
        ///
        /// Pre-order traversal visits a node before either of its subtrees.
        pub struct IterPreOrder<'a, T> {
            current_node: Link<T>,
            count: usize,
            elem: Option<&'a T>,
            _boo: PhantomData<&'a T>,
        }

        impl<'a, T> IterPreOrder<'a, T> {
            /// Creates a pre-order iterator starting at `root`.
            pub(crate) fn new(root: Link<T>, count: usize) -> Self {
                Self {
                    current_node: root,
                    count,
                    elem: None,
                    _boo: PhantomData,
                }
            }
        }

        impl<'a, T> Iterator for IterPreOrder<'a, T> {
            type Item = &'a T;

            fn next(&mut self) -> Option<Self::Item> {
                if self.count > 0 {
                    self.count -= 1;
                    if let Some(node) = self.current_node {
                        unsafe {
                            self.elem = Some(&node.as_ref().value);
                            self.current_node = successor_of_node_pre_order(node);
                        }
                    } else {
                        self.elem = None;
                    }
                } else {
                    self.elem = None;
                }
                self.elem
            }

            fn size_hint(&self) -> (usize, Option<usize>) {
                (self.count, Some(self.count))
            }
        }
    }

    pub use dfs_post_order::IterPostOrder;

    pub(crate) use dfs_post_order::{leaf_post_order, successor_of_node_post_order};

    mod dfs_post_order {
        use super::{Link, Node, NonNull};
        use std::marker::PhantomData;

        /// Returns the next node in a post-order (`Left -> Right -> Node`, or `LRN`) traversal.
        ///
        /// # Safety
        ///
        /// `current_node` must point to a live node in the current tree and all
        /// traversed parent/child links must be valid.
        pub unsafe fn successor_of_node_post_order<T>(current_node: NonNull<Node<T>>) -> Link<T> {
            unsafe {
                if let Some(parent) = current_node.as_ref().parent {
                    if let Some(right) = parent.as_ref().right {
                        if std::ptr::eq(current_node.as_ptr(), right.as_ptr()) {
                            Some(parent)
                        } else {
                            Some(leaf_post_order(right))
                        }
                    } else {
                        Some(parent)
                    }
                } else {
                    None
                }
            }
        }

        /// Returns the first leaf visited by a post-order traversal starting at `node`.
        ///
        /// # Safety
        ///
        /// `node` must point to a live node and all descendant links traversed by
        /// this function must be valid.
        pub unsafe fn leaf_post_order<T>(node: NonNull<Node<T>>) -> NonNull<Node<T>> {
            unsafe {
                if let Some(left) = node.as_ref().left {
                    leaf_post_order(left)
                } else if let Some(right) = node.as_ref().right {
                    leaf_post_order(right)
                } else {
                    node
                }
            }
        }

        /// Iterator over a tree in post-order (`Left -> Right -> Node`, or `LRN`).
        ///
        /// Post-order traversal visits both subtrees before the current node.
        pub struct IterPostOrder<'a, T> {
            current_node: Link<T>,
            count: usize,
            _boo: PhantomData<&'a T>,
        }

        impl<'a, T> IterPostOrder<'a, T> {
            /// Creates a post-order iterator starting at the first post-order node.
            pub(crate) fn new(root: Link<T>, count: usize) -> Self {
                Self {
                    current_node: root,
                    count,
                    _boo: PhantomData,
                }
            }
        }

        impl<'a, T> Iterator for IterPostOrder<'a, T> {
            type Item = &'a T;

            fn next(&mut self) -> Option<Self::Item> {
                if self.count == 0 {
                    return None;
                }

                let node = self.current_node?;

                unsafe {
                    let value = &node.as_ref().value;
                    self.current_node = successor_of_node_post_order(node);
                    self.count -= 1;
                    Some(value)
                }
            }

            fn size_hint(&self) -> (usize, Option<usize>) {
                (self.count, Some(self.count))
            }
        }
    }

    /// Breadth-First Search
    mod bfs {
        use super::{Node, NonNull};
        use std::collections::VecDeque;

        /// Appends tree values to `ret` in breadth-first / level-order.
        pub fn iter_level_order_impl<T>(root: NonNull<Node<T>>, ret: &mut Vec<&T>) {
            let mut deque: VecDeque<NonNull<Node<T>>> = VecDeque::new();
            unsafe {
                deque.push_back(root);
                let mut node: NonNull<Node<T>>;
                while !deque.is_empty() {
                    node = deque.pop_front().unwrap();
                    ret.push(&node.as_ref().value);
                    if let Some(left) = node.as_ref().left {
                        deque.push_back(left);
                    }
                    if let Some(right) = node.as_ref().right {
                        deque.push_back(right);
                    }
                }
            }
        }
    }

    pub(crate) use bfs::iter_level_order_impl;
}

/// Internal node representation used by the Red-Black Tree.
///
/// Nodes are allocated on the heap and connected using [`NonNull`] pointers.
/// The tree owns the allocated nodes and is responsible for releasing them.
///
/// `Node` and [`Link`] are crate-private implementation details and are not
/// exposed through the public API.
pub mod node{

    use std::ptr::NonNull;

    /// A single node in the Red-Black Tree.
    ///
    /// Each node stores:
    ///
    /// - a link to its left child;
    /// - a link to its right child;
    /// - a link to its parent;
    /// - its Red-Black color;
    /// - the stored value.
    ///
    /// Tree links are represented by [`Link<T>`], which is an
    /// `Option<NonNull<Node<T>>>`.
    ///
    /// A `None` link represents the absence of a parent or child, while
    /// `Some(pointer)` refers to another allocated node.
    ///
    /// Memory ownership is managed by [`crate::RedBlackTree`]. The pointers stored
    /// here are non-owning links between nodes.
    #[derive(Debug)]
    pub(crate) struct Node<T> {
        /// Left child of this node.
        pub(crate) left: Link<T>,

        /// Right child of this node.
        pub(crate) right: Link<T>,

        /// Parent of this node.
        ///
        /// The root node has no parent.
        pub(crate) parent: Link<T>,

        /// Red-Black color of the node.
        ///
        /// `true` means red and `false` means black.
        pub(crate) is_red: bool,

        /// Value stored in this node.
        pub(crate) value: T,
    }

    /// A link between nodes in the tree.
    ///
    /// `None` represents a missing parent or child.
    ///
    /// `Some(ptr)` contains a non-null pointer to another allocated [`Node`].
    ///
    /// Using `Option<NonNull<Node<T>>>` allows the implementation to represent
    /// nullable tree links while keeping direct pointer-based navigation between
    /// parents and children.
    pub(crate) type Link<T> = Option<NonNull<Node<T>>>;

    impl<T: Default> Node<T> {
        /// Creates the sentinel head node together with the initial tree root.
        ///
        /// The sentinel does not represent a value stored by the user. Its
        /// `value` field is initialized with [`Default::default`] and its left
        /// child becomes the first actual node in the tree.
        ///
        /// The initial root node is created as black, as required by the
        /// Red-Black Tree invariants.
        ///
        /// # Returns
        ///
        /// A link to the newly allocated sentinel node.
        ///
        /// # Implementation
        ///
        /// Both the sentinel and the root node are allocated on the heap.
        /// Ownership of these allocations is transferred to the tree and later
        /// recovered when the tree releases its nodes.
        pub(crate) fn new_fixed_head(value: T) -> Link<T> {
            let fixed_head = Box::into_non_null(Box::new(Self {
                left: None,
                right: None,
                parent: None,
                is_red: false,
                value: T::default(),
            }));
            unsafe {
                (*fixed_head.as_ptr()).left = Node::new_black(value);
            }
            Some(fixed_head)
        }
    }

    impl<T> Node<T> {
        /// Allocates a new black node.
        ///
        /// The node is created without a parent or children.
        ///
        /// # Returns
        ///
        /// A non-null link to the newly allocated node.
        ///
        /// The allocation becomes owned by the tree and must eventually be
        /// released by the tree implementation.
        pub(crate) fn new_black(value: T) -> Link<T> {
            let new = Box::into_non_null(Box::new(Self {
                left: None,
                right: None,
                parent: None,
                is_red: false,
                value,
            }));

            Some(new)
        }

        /// Allocates a new red node with the specified parent.
        ///
        /// Newly inserted Red-Black Tree nodes are initially red. The balancing
        /// algorithm may later recolor the node or rotate the surrounding
        /// subtree.
        ///
        /// The new node has no children.
        ///
        /// # Parameters
        ///
        /// - `value` — value stored in the node.
        /// - `parent` — non-null pointer to the node's parent.
        ///
        /// # Returns
        ///
        /// A non-null link to the newly allocated node.
        ///
        /// The allocation becomes owned by the tree and must eventually be
        /// released by the tree implementation.
        pub(crate) fn new_red(value: T, parent: NonNull<Node<T>>) -> Link<T> {
            let new = Box::into_non_null(Box::new(Self {
                left: None,
                right: None,
                parent: Some(parent),
                is_red: true,
                value,
            }));

            Some(new)
        }
    }
}


pub mod validation{
    use crate::node::Link;
    use crate::tree::RedBlackTree;

    impl<T: Ord + Default> RedBlackTree<T> {
        // red-red violations,
        // min black-height,
        // max black-height,
        // BST ordering,
        // parent links,
        // reachable node count
        unsafe fn validate(
            node: &Link<T>,
            expected_parent: Link<T>,
            parent_is_red: bool,
            black_height: usize,
            min: Option<&T>,
            max: Option<&T>,
        ) -> (usize, usize, usize, bool, bool, usize) {
            unsafe {
                if let Some(n) = node {
                    let value = &n.as_ref().value;

                    // 1. Check parent
                    let parent_valid = match (n.as_ref().parent, expected_parent) {
                        (None, None) => true,

                        (Some(actual), Some(expected)) => {
                            std::ptr::eq(actual.as_ptr(), expected.as_ptr())
                        }

                        _ => false,
                    };

                    // 2. Check BST ordering
                    if let Some(min) = min
                        && value <= min
                    {
                        return (0, 0, 0, false, parent_valid, 1);
                    }

                    if let Some(max) = max
                        && value >= max
                    {
                        return (0, 0, 0, false, parent_valid, 1);
                    }

                    let is_red = n.as_ref().is_red;

                    // 3. A red node cannot have a red parent.
                    let red_red = if parent_is_red && is_red { 1 } else { 0 };

                    // 4. Black height
                    let black_height = if is_red {
                        black_height
                    } else {
                        black_height + 1
                    };

                    let left = Self::validate(
                        &n.as_ref().left,
                        Some(*n),
                        is_red,
                        black_height,
                        min,
                        Some(value),
                    );

                    let right = Self::validate(
                        &n.as_ref().right,
                        Some(*n),
                        is_red,
                        black_height,
                        Some(value),
                        max,
                    );

                    (
                        red_red + left.0 + right.0,
                        std::cmp::min(left.1, right.1),
                        std::cmp::max(left.2, right.2),
                        left.3 && right.3,
                        parent_valid && left.4 && right.4,
                        1 + left.5 + right.5,
                    )
                } else {
                    (0, black_height, black_height, true, true, 0)
                }
            }
        }

        pub fn is_valid(&self) -> bool {
            unsafe {
                // tree is empty
                if self.count == 0 {
                    return match self.fixed_head {
                        None => true,

                        Some(fixed_head) => (*fixed_head.as_ptr()).left.is_none(),
                    };
                }

                // count > 0, so sentinel must exist.
                let Some(fixed_head) = self.fixed_head else {
                    return false;
                };

                // And root must exist.
                let root_link = (*fixed_head.as_ptr()).left;

                let Some(root) = root_link else {
                    return false;
                };

                // Root is always BLACK
                if root.as_ref().is_red {
                    return false;
                }

                // Root has no parent
                if root.as_ref().parent.is_some() {
                    return false;
                }

                let result = Self::validate(&root_link, None, false, 0, None, None);

                let red_red = result.0;
                let black_height_min = result.1;
                let black_height_max = result.2;
                let bst_valid = result.3;
                let parents_valid = result.4;
                let reachable_nodes = result.5;

                red_red == 0
                    && black_height_min == black_height_max
                    && bst_valid
                    && parents_valid
                    && reachable_nodes == self.count
            }
        }
    }
}


pub mod tree{
    use std::cmp::Ordering;
    use std::fmt::{Debug, Display};

    use crate::node::{Link, Node};

    use std::marker::PhantomData;
    use std::ptr::NonNull;

    use crate::iter::{IterInOrder, Range, leftmost_child_in_order, successor_of_node_in_order};

    use crate::iter::{
        IterReverseInOrder, rightmost_child_reverse_in_order, successor_of_node_reverse_in_order,
    };

    use crate::iter::{IterPreOrder, successor_of_node_pre_order};

    use crate::iter::{IterPostOrder, leaf_post_order, successor_of_node_post_order};

    use crate::iter::iter_level_order_impl;

    /// A self-balancing Red-Black Tree.
    ///
    /// `RedBlackTree` stores unique values in sorted order.
    ///
    /// Insert, lookup and removal operations have logarithmic
    /// expected tree height due to Red-Black Tree balancing.
    ///
    /// # Examples
    ///
    /// ```
    /// use rbtree_extended::RedBlackTree;
    ///
    /// let mut tree = RedBlackTree::new();
    ///
    /// tree.insert(3);
    /// tree.insert(1);
    /// tree.insert(2);
    ///
    /// assert_eq!(tree.len(), 3);
    /// assert!(tree.contains(&2));
    /// ```
    pub struct RedBlackTree<T: Ord + Default> {
        pub(crate) fixed_head: Link<T>,
        pub(crate) count: usize,
        _marker: PhantomData<T>,
    }

    enum OperationPut {
        Left,
        Right,
        FlipColors,
        Nothing,
    }

    enum OperationRemove {
        RedLeaf,
        BlackLeaf,
        NodeWithChildren,
        BlackNodeWithRedLeaf,
    }

    enum OperationRemoveBlackLeaf {
        LeftRedABlackBRedCleaf,                      // 2.1.1.1
        RightRedABlackBRedCleaf,                     // 2.1.1.2
        LeftRedABlackBleaf,                          // 2.1.2.1
        RightRedABlackBleaf,                         // 2.1.2.2
        BlackARedBWithBlackChildrenLeaf,             // 2.2.4
        BlackARedBWithBlackChildrenRightHaveRedLeaf, // 2.2.1
        BlackALeftBlackBRedDleaf,                    // 2.3.1.1
        BlackARightBlackBRedDleaf,                   // 2.3.1.2
        BlackALeftBlackBleaf,                        // 2.3.2.1
        BlackARightBlackBleaf,                       // 2.3.2.2
        Root,
        Unimplemented,
    }

    impl<T: Ord + Default + Display> RedBlackTree<T> {
        /// Exports the tree in Graphviz DOT format.
        ///
        /// The returned string can be rendered using Graphviz-compatible tools.
        ///
        /// An empty tree produces a valid empty DOT graph.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.insert(10);
        /// tree.insert(5);
        /// tree.insert(20);
        ///
        /// let dot = tree.to_dot();
        ///
        /// println!("{dot}");
        /// ```
        pub fn to_dot(&self) -> String {
            unsafe {
                let Some(fixed_head) = self.fixed_head else {
                    return "digraph Tree {}".into();
                };

                let Some(root) = (*fixed_head.as_ptr()).left else {
                    return "digraph Tree {}".into();
                };

                format!(
                    "\ndigraph Tree {{\n\tratio = fill;\n\tnode [style=filled fontcolor=\"white\"];\n{}}}",
                    helper_display_tree(root)
                )
            }
        }
    }

    impl<T: Ord + Default> RedBlackTree<T> {
        /// Creates an empty Red-Black Tree.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let tree = RedBlackTree::<i32>::new();
        ///
        /// assert!(tree.is_empty());
        /// ```
        pub fn new() -> Self {
            Self {
                fixed_head: None,
                count: 0,
                _marker: PhantomData,
            }
        }

        /// Returns the number of values stored in the tree.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.insert(10);
        /// tree.insert(20);
        ///
        /// assert_eq!(tree.len(), 2);
        /// ```
        pub fn len(&self) -> usize {
            self.count
        }

        /// Returns `true` if the tree contains no values.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::<i32>::new();
        /// assert!(tree.is_empty());
        ///
        /// tree.insert(10);
        /// assert!(!tree.is_empty());
        /// ```
        pub fn is_empty(&self) -> bool {
            self.count == 0
        }

        /// Removes all values from the tree.
        ///
        /// After calling `clear`, the tree is empty and can be reused.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([1, 2, 3]);
        ///
        /// tree.clear();
        ///
        /// assert!(tree.is_empty());
        /// assert_eq!(tree.len(), 0);
        /// ```
        pub fn clear(&mut self) {
            unsafe {
                if let Some(fixed_head) = self.fixed_head {
                    let root = (*fixed_head.as_ptr()).left;

                    (*fixed_head.as_ptr()).left = None;

                    self.remove_tree(root);
                }

                debug_assert_eq!(self.count, 0);
            }
        }

        /// Returns the smallest value in the tree.
        ///
        /// Returns `None` if the tree is empty.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([8, 3, 10, 1]);
        ///
        /// assert_eq!(tree.first(), Some(&1));
        /// ```
        pub fn first(&self) -> Option<&T> {
            self.minimum()
        }

        /// Returns the largest value in the tree.
        ///
        /// Returns `None` if the tree is empty.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([8, 3, 10, 14]);
        ///
        /// assert_eq!(tree.last(), Some(&14));
        /// ```
        pub fn last(&self) -> Option<&T> {
            self.maximum()
        }

        fn minimum(&self) -> Option<&T> {
            unsafe {
                let root = self.get_root()?;
                let node = self.find_min(root);
                Some(&node.as_ref().value)
            }
        }

        fn maximum(&self) -> Option<&T> {
            unsafe {
                let root = self.get_root()?;
                let node = self.find_max(root);

                Some(&node.as_ref().value)
            }
        }

        /// Returns the height of the tree.
        ///
        /// An empty tree has height `0`.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// assert_eq!(tree.height(), 0);
        ///
        /// tree.insert(10);
        /// assert_eq!(tree.height(), 1);
        /// ```
        pub fn height(&self) -> usize {
            unsafe fn height_from<T>(node: Link<T>) -> usize {
                unsafe {
                    match node {
                        None => 0,

                        Some(node) => {
                            let left_height = height_from(node.as_ref().left);
                            let right_height = height_from(node.as_ref().right);

                            1 + left_height.max(right_height)
                        }
                    }
                }
            }

            unsafe { height_from(self.get_root()) }
        }

        /// Returns `true` if the tree contains `value`.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([1, 3, 5]);
        ///
        /// assert!(tree.contains(&3));
        /// assert!(!tree.contains(&4));
        /// ```
        pub fn contains(&self, value: &T) -> bool {
            !find_node(self.get_root(), value).is_none()
        }

        /// Inserts a value into the tree.
        ///
        /// Returns `true` if the value was inserted.
        ///
        /// Returns `false` if the value already exists.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        ///
        /// assert!(tree.insert(10));
        /// assert!(!tree.insert(10));
        /// ```
        pub fn insert(&mut self, value: T) -> bool {
            unsafe {
                if let Some(fixed_head) = self.fixed_head {
                    if (*fixed_head.as_ptr()).left.is_none() {
                        (*fixed_head.as_ptr()).left = Node::new_black(value);
                        self.count += 1;
                        return true;
                    }

                    let parent = self.find_put_parent_candidate(self.get_root(), &value);

                    if let Some(parent) = parent {
                        if self.attach_node(parent, value) {
                            self.put_balancing(parent);
                        } else {
                            return false;
                        }
                    } else {
                        return false;
                    }
                } else {
                    self.fixed_head = Node::new_fixed_head(value);
                }

                self.count += 1;
                true
            }
        }

        /// Removes a value from the tree.
        ///
        /// Returns `true` if the value existed and was removed.
        ///
        /// Use [`RedBlackTree::take`] when ownership of the removed value is needed.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.insert(10);
        ///
        /// assert!(tree.remove(&10));
        /// assert!(!tree.contains(&10));
        /// assert!(!tree.remove(&10));
        /// ```
        pub fn remove(&mut self, value: &T) -> bool {
            self.take(value).is_some()
        }

        /// Inserts `value` into the tree, replacing an existing equal value.
        ///
        /// If the tree already contains a value that compares equal to `value`,
        /// the existing value is replaced and returned.
        ///
        /// If no equal value exists, `value` is inserted and `None` is returned.
        ///
        /// This is especially useful for custom types whose [`Ord`] implementation
        /// compares only a key field.
        ///
        /// # Examples
        ///
        /// ```
        /// use std::cmp::Ordering;
        /// use rbtree_extended::RedBlackTree;
        ///
        /// #[derive(Debug, Default)]
        /// struct User {
        ///     id: u32,
        ///     name: String,
        /// }
        ///
        /// impl PartialEq for User {
        ///     fn eq(&self, other: &Self) -> bool {
        ///         self.id == other.id
        ///     }
        /// }
        ///
        /// impl Eq for User {}
        ///
        /// impl PartialOrd for User {
        ///     fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        ///         Some(self.cmp(other))
        ///     }
        /// }
        ///
        /// impl Ord for User {
        ///     fn cmp(&self, other: &Self) -> Ordering {
        ///         self.id.cmp(&other.id)
        ///     }
        /// }
        ///
        /// let mut users = RedBlackTree::new();
        ///
        /// users.insert(User {
        ///     id: 1,
        ///     name: "Alice".into(),
        /// });
        ///
        /// let old = users.replace(User {
        ///     id: 1,
        ///     name: "Bob".into(),
        /// });
        ///
        /// assert_eq!(old.unwrap().name, "Alice");
        /// assert_eq!(users.first().unwrap().name, "Bob");
        /// ```
        pub fn replace(&mut self, value: T) -> Option<T> {
            unsafe {
                if let Some(mut node) = find_node(self.get_root(), &value) {
                    return Some(std::mem::replace(&mut node.as_mut().value, value));
                }
            }

            self.insert(value);

            None
        }

        unsafe fn take_node(&mut self, mut node: NonNull<Node<T>>) -> Option<T> {
            unsafe {
                // Save the original value before the internal removal algorithm
                // starts swapping values between nodes.
                let removed_value = std::mem::take(&mut node.as_mut().value);

                if !self.remove_node(node) {
                    return None;
                }

                self.count -= 1;

                Some(removed_value)
            }
        }

        /// Removes and returns the value equal to `value`.
        ///
        /// Returns `None` if the value is not present in the tree.
        ///
        /// Unlike [`RedBlackTree::remove`], this method gives ownership of the
        /// removed value back to the caller.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([10, 5, 20]);
        ///
        /// assert_eq!(tree.take(&10), Some(10));
        /// assert!(!tree.contains(&10));
        /// assert_eq!(tree.take(&100), None);
        /// ```
        pub fn take(&mut self, value: &T) -> Option<T> {
            if self.is_empty() {
                return None;
            }

            unsafe {
                let node = find_node(self.get_root(), value)?;
                self.take_node(node)
            }
        }

        /// Retains only the values specified by the predicate.
        ///
        /// In other words, removes every value for which `f(&value)` returns `false`.
        ///
        /// The predicate receives a shared reference to each stored value.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([1, 2, 3, 4, 5, 6]);
        ///
        /// tree.retain(|value| value % 2 == 0);
        ///
        /// assert_eq!(
        ///     tree.iter().copied().collect::<Vec<_>>(),
        ///     vec![2, 4, 6]
        /// );
        /// ```
        ///
        /// Retaining no values empties the tree:
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([1, 2, 3]);
        ///
        /// tree.retain(|_| false);
        ///
        /// assert!(tree.is_empty());
        /// ```
        pub fn retain<F>(&mut self, mut f: F)
        where
            F: FnMut(&T) -> bool,
        {
            let mut retained = Self::new();

            while let Some(value) = self.pop_first() {
                if f(&value) {
                    retained.insert(value);
                }
            }

            *self = retained;
        }

        /// Removes and returns the smallest value in the tree.
        ///
        /// Returns `None` if the tree is empty.
        ///
        /// This operation is useful when values need to be processed in
        /// ascending order.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([8, 3, 10, 1, 6]);
        ///
        /// assert_eq!(tree.pop_first(), Some(1));
        /// assert_eq!(tree.pop_first(), Some(3));
        /// assert_eq!(tree.len(), 3);
        /// ```
        pub fn pop_first(&mut self) -> Option<T> {
            unsafe {
                let root = self.get_root()?;
                let node = self.find_min(root);

                self.take_node(node)
            }
        }

        /// Removes and returns the largest value in the tree.
        ///
        /// Returns `None` if the tree is empty.
        ///
        /// This operation can be used to implement a priority queue where the
        /// greatest value represents the highest priority.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([8, 3, 10, 1, 6]);
        ///
        /// assert_eq!(tree.pop_last(), Some(10));
        /// assert_eq!(tree.pop_last(), Some(8));
        /// assert_eq!(tree.len(), 3);
        /// ```
        pub fn pop_last(&mut self) -> Option<T> {
            unsafe {
                let root = self.get_root()?;
                let node = self.find_max(root);

                self.take_node(node)
            }
        }

        /// Returns a reference to the stored value equal to `value`.
        ///
        /// Returns `None` if no matching value exists.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([1, 3, 5]);
        ///
        /// assert_eq!(tree.get(&3), Some(&3));
        /// assert_eq!(tree.get(&4), None);
        /// ```
        pub fn get(&self, value: &T) -> Option<&T> {
            unsafe {
                let node = find_node(self.get_root(), value)?;
                Some(&node.as_ref().value)
            }
        }

        /// Returns the next greater value in sorted order.
        ///
        /// Returns `None` if `value` is not present or if it is the largest value.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([1, 3, 5, 7]);
        ///
        /// assert_eq!(tree.successor(&3), Some(&5));
        /// assert_eq!(tree.successor(&7), None);
        /// ```
        pub fn successor(&self, value: &T) -> Option<&T> {
            unsafe {
                let node = find_node(self.get_root(), value)?;

                // Case 1:
                // there is a right subtree - successor = minimum element on the right
                if let Some(right) = node.as_ref().right {
                    let successor = self.find_min(right);
                    return Some(&successor.as_ref().value);
                }

                // Case 2:
                // there is no right subtree
                // Move up while the current node is a right child
                let mut current = node;
                let mut parent = current.as_ref().parent;

                while let Some(p) = parent {
                    if let Some(left) = p.as_ref().left
                        && std::ptr::eq(left.as_ptr(), current.as_ptr())
                    {
                        return Some(&p.as_ref().value);
                    }

                    current = p;
                    parent = p.as_ref().parent;
                }

                None
            }
        }

        /// Returns the previous smaller value in sorted order.
        ///
        /// Returns `None` if `value` is not present or if it is the smallest value.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([1, 3, 5, 7]);
        ///
        /// assert_eq!(tree.predecessor(&5), Some(&3));
        /// assert_eq!(tree.predecessor(&1), None);
        /// ```
        pub fn predecessor(&self, value: &T) -> Option<&T> {
            unsafe {
                let node = find_node(self.get_root(), value)?;

                // Case 1:
                // there is a left subtree - predecessor = maximum element on the left
                if let Some(left) = node.as_ref().left {
                    let predecessor = self.find_max(left);
                    return Some(&predecessor.as_ref().value);
                }

                // Case 2:
                // there is no left subtree
                // Move up while the current node is a left child
                let mut current = node;
                let mut parent = current.as_ref().parent;

                while let Some(p) = parent {
                    if let Some(right) = p.as_ref().right
                        && std::ptr::eq(right.as_ptr(), current.as_ptr())
                    {
                        return Some(&p.as_ref().value);
                    }

                    current = p;
                    parent = p.as_ref().parent;
                }

                None
            }
        }

        /// Returns the first value greater than or equal to `value`.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([1, 3, 6, 8]);
        ///
        /// assert_eq!(tree.lower_bound(&5), Some(&6));
        /// assert_eq!(tree.lower_bound(&6), Some(&6));
        /// ```
        pub fn lower_bound(&self, value: &T) -> Option<&T> {
            unsafe {
                let mut current = self.get_root();
                let mut candidate: Link<T> = None;

                while let Some(node) = current {
                    match node.as_ref().value.cmp(value) {
                        Ordering::Less => {
                            current = node.as_ref().right;
                        }

                        Ordering::Equal => {
                            return Some(&node.as_ref().value);
                        }

                        Ordering::Greater => {
                            candidate = Some(node);
                            current = node.as_ref().left;
                        }
                    }
                }

                candidate.map(|node| &node.as_ref().value)
            }
        }

        /// Returns the first value strictly greater than `value`.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([1, 3, 6, 8]);
        ///
        /// assert_eq!(tree.upper_bound(&6), Some(&8));
        /// assert_eq!(tree.upper_bound(&8), None);
        /// ```
        pub fn upper_bound(&self, value: &T) -> Option<&T> {
            unsafe {
                let mut current = self.get_root();
                let mut candidate: Link<T> = None;

                while let Some(node) = current {
                    match node.as_ref().value.cmp(value) {
                        Ordering::Less | Ordering::Equal => {
                            current = node.as_ref().right;
                        }
                        Ordering::Greater => {
                            candidate = Some(node);
                            current = node.as_ref().left;
                        }
                    }
                }

                candidate.map(|node| &node.as_ref().value)
            }
        }

        /// Returns an iterator over values in the inclusive range `[min, max]`.
        ///
        /// Values are yielded in ascending order.
        ///
        /// The iterator is lazy: values are produced only as they are requested,
        /// rather than being collected into an intermediate `Vec`.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([1, 3, 5, 7, 9, 11]);
        ///
        /// let values: Vec<_> = tree
        ///     .range(&3, &9)
        ///     .copied()
        ///     .collect();
        ///
        /// assert_eq!(values, vec![3, 5, 7, 9]);
        /// ```
        pub fn range(&self, min: &T, max: &T) -> Range<'_, T> {
            Range::new(self.get_root(), min, max)
        }

        /// Returns the next value in an in-order (`LNR`) traversal.
        ///
        /// For a binary search tree, in-order traversal visits values in ascending order.
        ///
        /// Returns `None` if `value` is not present or has no successor in this traversal.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([4, 2, 6, 1, 3, 5, 7]);
        ///
        /// assert_eq!(tree.successor_dfs_in_order(4), Some(&5));
        /// ```
        pub fn successor_dfs_in_order(&self, value: T) -> Option<&T> {
            unsafe {
                let node = find_node(self.get_root(), &value);
                if let Some(n) = node
                    && let Some(nodesucc) = successor_of_node_in_order(n)
                {
                    return Some(&nodesucc.as_ref().value);
                }
                None
            }
        }

        /// Returns the next value in reverse in-order (`RNL`) traversal.
        ///
        /// For a binary search tree, reverse in-order traversal visits values in
        /// descending order.
        ///
        /// Returns `None` if `value` is not present or has no successor in this traversal.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([4, 2, 6, 1, 3, 5, 7]);
        ///
        /// assert_eq!(tree.successor_dfs_reverse_in_order(6), Some(&5));
        /// ```
        pub fn successor_dfs_reverse_in_order(&self, value: T) -> Option<&T> {
            unsafe {
                if let Some(node) = find_node(self.get_root(), &value)
                    && let Some(next) = successor_of_node_reverse_in_order(node)
                {
                    return Some(&next.as_ref().value);
                }
                None
            }
        }

        /// Returns the next value in post-order (`LRN`) traversal.
        ///
        /// Post-order visits the left subtree, then the right subtree,
        /// and finally the current node.
        ///
        /// Returns `None` if `value` is not present or has no successor in this traversal.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([4, 2, 6, 1, 3, 5, 7]);
        ///
        /// // Post-order: 1, 3, 2, 5, 7, 6, 4
        /// assert_eq!(tree.successor_dfs_post_order(3), Some(&2));
        /// assert_eq!(tree.successor_dfs_post_order(2), Some(&5));
        /// assert_eq!(tree.successor_dfs_post_order(4), None);
        /// ```
        pub fn successor_dfs_post_order(&self, value: T) -> Option<&T> {
            unsafe {
                if let Some(n) = find_node(self.get_root(), &value)
                    && let Some(nodesucc) = successor_of_node_post_order(n)
                {
                    return Some(&nodesucc.as_ref().value);
                }
                None
            }
        }

        /// Returns the next value in pre-order (`NLR`) traversal.
        ///
        /// Pre-order visits the current node first, followed by the left and right
        /// subtrees.
        ///
        /// Returns `None` if `value` is not present or has no successor in this traversal.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([4, 2, 6, 1, 3, 5, 7]);
        ///
        /// let first = *tree.iter_preorder().next().unwrap();
        /// assert_eq!(tree.successor_dfs_pre_order(first), tree.iter_preorder().nth(1));
        /// ```
        pub fn successor_dfs_pre_order(&self, value: T) -> Option<&T> {
            unsafe {
                if let Some(n) = find_node(self.get_root(), &value)
                    && let Some(nodesucc) = successor_of_node_pre_order(n)
                {
                    return Some(&nodesucc.as_ref().value);
                }
                None
            }
        }

        fn get_root(&self) -> Link<T> {
            if let Some(fixed_head) = self.fixed_head {
                unsafe { (*fixed_head.as_ptr()).left }
            } else {
                None
            }
        }

        unsafe fn operation_remove(&self, node_x: &NonNull<Node<T>>) -> OperationRemove {
            unsafe {
                if node_x.as_ref().is_red
                    && node_x.as_ref().left.is_none()
                    && node_x.as_ref().right.is_none()
                {
                    return OperationRemove::RedLeaf;
                }
                if node_x.as_ref().is_red
                    && node_x.as_ref().left.is_some()
                    && node_x.as_ref().right.is_some()
                {
                    return OperationRemove::NodeWithChildren;
                }
                if !node_x.as_ref().is_red {
                    if node_x.as_ref().left.is_some() && node_x.as_ref().right.is_some() {
                        return OperationRemove::NodeWithChildren;
                    } else if node_x.as_ref().left.is_some() && node_x.as_ref().right.is_none() {
                        if let Some(left) = node_x.as_ref().left
                            && left.as_ref().is_red
                            && left.as_ref().left.is_none()
                            && left.as_ref().right.is_none()
                        {
                            return OperationRemove::BlackNodeWithRedLeaf;
                        }
                    } else if node_x.as_ref().left.is_none() && node_x.as_ref().right.is_none() {
                        return OperationRemove::BlackLeaf;
                    }
                }
                panic!();
            }
        }

        unsafe fn operation_remove_black_leaf(
            &self,
            node_x: &NonNull<Node<T>>,
        ) -> OperationRemoveBlackLeaf {
            unsafe {
                if let Some(node_a) = node_x.as_ref().parent {
                    if node_a.as_ref().is_red {
                        if let Some(node_b) = node_a.as_ref().left
                            && !std::ptr::eq(node_b.as_ptr(), node_x.as_ptr())
                            && !node_b.as_ref().is_red
                        {
                            if let Some(node_c) = node_b.as_ref().left
                                && node_c.as_ref().is_red
                            {
                                return OperationRemoveBlackLeaf::LeftRedABlackBRedCleaf;
                                // 2.1.1.1
                            }

                            // sibling B is black and its left child is either absent or also black
                            return OperationRemoveBlackLeaf::LeftRedABlackBleaf;
                            // 2.1.2.1
                        }

                        if let Some(node_b) = node_a.as_ref().right
                            && !std::ptr::eq(node_b.as_ptr(), node_x.as_ptr())
                            && !node_b.as_ref().is_red
                        {
                            if let Some(node_c) = node_b.as_ref().left
                                && node_c.as_ref().is_red
                            {
                                return OperationRemoveBlackLeaf::RightRedABlackBRedCleaf;
                                // 2.1.1.2
                            }

                            // sibling B is black and its left child is either absent or also black
                            return OperationRemoveBlackLeaf::RightRedABlackBleaf;
                            // 2.1.2.2
                        }
                    } else {
                        if let Some(node_b) = node_a.as_ref().left
                            && !std::ptr::eq(node_b.as_ptr(), node_x.as_ptr())
                        {
                            if node_b.as_ref().is_red && node_b.as_ref().right.is_some() {
                                let node_c = node_b.as_ref().right.unwrap();
                                if !node_c.as_ref().is_red {
                                    if node_c.as_ref().left.is_some()
                                        && let Some(node_d) = node_c.as_ref().left
                                        && node_d.as_ref().is_red
                                    {
                                        return OperationRemoveBlackLeaf::BlackARedBWithBlackChildrenRightHaveRedLeaf;
                                        // 2.2.1
                                    }
                                    return OperationRemoveBlackLeaf::BlackARedBWithBlackChildrenLeaf;
                                    // 2.2.2
                                }
                            }
                            if !node_b.as_ref().is_red
                                && node_b.as_ref().left.is_some()
                                && let Some(node_d) = node_b.as_ref().left
                                && node_d.as_ref().is_red
                            {
                                return OperationRemoveBlackLeaf::BlackALeftBlackBRedDleaf;
                                // 2.3.1.1
                            }
                            if !node_b.as_ref().is_red {
                                return OperationRemoveBlackLeaf::BlackALeftBlackBleaf;
                                // 2.3.2.1
                            }
                        }
                        if let Some(node_b) = node_a.as_ref().right
                            && !std::ptr::eq(node_b.as_ptr(), node_x.as_ptr())
                        {
                            if !node_b.as_ref().is_red
                                && node_b.as_ref().left.is_some()
                                && let Some(node_d) = node_b.as_ref().left
                                && node_d.as_ref().is_red
                            {
                                return OperationRemoveBlackLeaf::BlackARightBlackBRedDleaf;
                                // 2.3.1.2
                            }
                            if !node_b.as_ref().is_red {
                                return OperationRemoveBlackLeaf::BlackARightBlackBleaf;
                                // 2.3.2.2
                            }
                        }
                    }
                } else {
                    return OperationRemoveBlackLeaf::Root;
                }
                OperationRemoveBlackLeaf::Unimplemented
            }
        }

        unsafe fn remove_black_leaf(&mut self, node_x: NonNull<Node<T>>) -> bool {
            unsafe {
                let mut next = node_x;
                let mut removed = false;
                loop {
                    match self.operation_remove_black_leaf(&next) {
                        OperationRemoveBlackLeaf::LeftRedABlackBRedCleaf => {
                            self.remove_black_leaf_2_1_1_1_balancing(&next);
                            if !removed {
                                removed = self.remove_leaf(node_x);
                            }
                            break;
                        }
                        OperationRemoveBlackLeaf::RightRedABlackBRedCleaf => {
                            self.remove_black_leaf_2_1_1_2_balancing(&next);
                            if !removed {
                                removed = self.remove_leaf(node_x);
                            }
                            break;
                        }
                        OperationRemoveBlackLeaf::LeftRedABlackBleaf => {
                            self.remove_black_leaf_2_1_2_1_balancing(&next);
                            if !removed {
                                removed = self.remove_leaf(node_x);
                            }
                            break;
                        }
                        OperationRemoveBlackLeaf::RightRedABlackBleaf => {
                            self.remove_black_leaf_2_1_2_2_balancing(&next);
                            if !removed {
                                removed = self.remove_leaf(node_x);
                            }
                            break;
                        }
                        OperationRemoveBlackLeaf::BlackARedBWithBlackChildrenRightHaveRedLeaf => {
                            self.remove_black_leaf_2_2_1_balancing(&next);
                            if !removed {
                                removed = self.remove_leaf(node_x);
                            }
                            break;
                        }
                        OperationRemoveBlackLeaf::BlackARedBWithBlackChildrenLeaf => {
                            self.remove_black_leaf_2_2_2_balancing(&next);
                            if !removed {
                                removed = self.remove_leaf(node_x);
                            }
                            break;
                        }
                        OperationRemoveBlackLeaf::BlackALeftBlackBRedDleaf => {
                            self.remove_black_leaf_2_3_1_1_balancing(&next);
                            if !removed {
                                removed = self.remove_leaf(node_x);
                            }
                            break;
                        }
                        OperationRemoveBlackLeaf::BlackARightBlackBRedDleaf => {
                            self.remove_black_leaf_2_3_1_2_balancing(&next);
                            if !removed {
                                removed = self.remove_leaf(node_x);
                            }
                            break;
                        }
                        OperationRemoveBlackLeaf::BlackALeftBlackBleaf => {
                            next = self.remove_black_leaf_2_3_2_1_balancing(&next);
                            if !removed {
                                removed = self.remove_leaf(node_x);
                            }
                        }
                        OperationRemoveBlackLeaf::BlackARightBlackBleaf => {
                            next = self.remove_black_leaf_2_3_2_2_balancing(&next);
                            if !removed {
                                removed = self.remove_leaf(node_x);
                            }
                        }
                        OperationRemoveBlackLeaf::Root => {
                            if !removed {
                                // We get here when the node_x being deleted is root
                                if let Some(fixed_head) = self.fixed_head {
                                    (*fixed_head.as_ptr()).left = None;
                                }
                                let _ = Box::from_raw(node_x.as_ptr());
                                removed = true;
                            }
                            break;
                        }
                        OperationRemoveBlackLeaf::Unimplemented => {
                            panic!("unimplemented black leaf removal case");
                        }
                    }
                }
                removed
            }
        }

        /// 2.1.1.1 remove black X
        ///
        /// ```text
        ///             P            P
        ///            //           //
        ///            A            B
        ///           / \          / \
        ///          B   X   =>   C   A
        ///         //\              /
        ///        C   D            D
        /// ```
        unsafe fn remove_black_leaf_2_1_1_1_balancing(&mut self, node_x: &NonNull<Node<T>>) {
            unsafe {
                let node_a = (*node_x.as_ptr()).parent.unwrap();
                let node_b = (*node_a.as_ptr()).left.unwrap();
                let node_d = (*node_b.as_ptr()).right;
                (*node_b.as_ptr()).parent = (*node_a.as_ptr()).parent;
                if let Some(ref mut parent) = (*node_b.as_ptr()).parent {
                    (*parent.as_ptr()).left = Some(node_b);
                }
                (*node_a.as_ptr()).left = node_d;
                if let Some(n_d) = node_d {
                    (*n_d.as_ptr()).parent = Some(node_a);
                }
                (*node_a.as_ptr()).is_red = false;
                (*node_b.as_ptr()).right = Some(node_a);
                (*node_a.as_ptr()).parent = Some(node_b);
                (*node_b.as_ptr()).is_red = true;
                if let Some(node_c) = (*node_b.as_ptr()).left {
                    (*node_c.as_ptr()).is_red = false;
                }
            }
        }

        /// 2.1.1.2 remove black X
        ///
        /// ```text
        ///             P              P
        ///            //             //
        ///           A               C
        ///          / \            /   \
        ///         X   B   =>     A     B
        ///            //           \   /
        ///            C             E D
        ///           / \
        ///          E   D
        /// ```
        unsafe fn remove_black_leaf_2_1_1_2_balancing(&mut self, node_x: &NonNull<Node<T>>) {
            unsafe {
                let node_a = (*node_x.as_ptr()).parent.unwrap();
                (*node_a.as_ptr()).is_red = false;
                let parent: NonNull<Node<T>> = (*node_a.as_ptr()).parent.unwrap();
                let node_b = (*node_a.as_ptr()).right.unwrap();
                let node_c = (*node_b.as_ptr()).left.unwrap();
                let node_e = (*node_c.as_ptr()).left;
                let node_d = (*node_c.as_ptr()).right;
                (*parent.as_ptr()).left = Some(node_c);
                (*node_c.as_ptr()).parent = Some(parent);
                (*node_b.as_ptr()).left = node_d;
                if let Some(n_d) = node_d {
                    (*n_d.as_ptr()).parent = Some(node_b);
                }
                (*node_c.as_ptr()).right = Some(node_b);
                (*node_b.as_ptr()).parent = Some(node_c);
                (*node_c.as_ptr()).left = Some(node_a);
                (*node_a.as_ptr()).parent = Some(node_c);
                (*node_a.as_ptr()).right = node_e;
                if let Some(n_e) = node_e {
                    (*n_e.as_ptr()).parent = Some(node_a);
                }
            }
        }

        /// 2.1.2.1 remove black X
        ///
        /// ```text
        ///              P            P
        ///             //           /
        ///            A            A
        ///           / \          //
        ///          B   X   =>   B
        ///
        /// ```
        unsafe fn remove_black_leaf_2_1_2_1_balancing(&mut self, node_x: &NonNull<Node<T>>) {
            unsafe {
                let node_a = (*node_x.as_ptr()).parent.unwrap();
                (*node_a.as_ptr()).is_red = false;
                if let Some(node_b) = (*node_a.as_ptr()).left {
                    (*node_b.as_ptr()).is_red = true;
                }
            }
        }

        /// 2.1.2.2 remove black X
        ///
        /// ```text
        ///             P            P
        ///            //           /
        ///            A     =>     B
        ///           / \          //\
        ///          X   B        A   D
        ///             / \        \
        ///            C   D        C
        /// ```
        unsafe fn remove_black_leaf_2_1_2_2_balancing(&mut self, node_x: &NonNull<Node<T>>) {
            unsafe {
                let node_a = (*node_x.as_ptr()).parent.unwrap();
                let node_b = (*node_a.as_ptr()).right.unwrap();
                let node_c = (*node_b.as_ptr()).left;
                let node_d = (*node_b.as_ptr()).right;
                let parent = (*node_a.as_ptr()).parent.unwrap();
                if let Some(left) = (*parent.as_ptr()).left {
                    if std::ptr::eq(node_a.as_ptr(), left.as_ptr()) {
                        (*parent.as_ptr()).left = Some(node_b);
                    } else {
                        (*parent.as_ptr()).right = Some(node_b);
                    }
                } else {
                    (*parent.as_ptr()).right = Some(node_b);
                }
                (*node_b.as_ptr()).parent = Some(parent);
                (*node_b.as_ptr()).left = Some(node_a);
                (*node_b.as_ptr()).right = node_d;
                if let Some(n_d) = node_d {
                    (*n_d.as_ptr()).parent = Some(node_b);
                }
                (*node_a.as_ptr()).parent = Some(node_b);
                (*node_a.as_ptr()).right = node_c;
                if let Some(n_c) = node_c {
                    (*n_c.as_ptr()).parent = Some(node_a);
                }
            }
        }

        /// 2.2.1 remove black X
        ///
        /// ```text
        ///            A               C
        ///          // \            //  \
        ///         B    X    =>    B     A
        ///          \               \   /
        ///           C               D E
        ///           //\
        ///          D   E
        /// ```
        unsafe fn remove_black_leaf_2_2_1_balancing(&mut self, node_x: &NonNull<Node<T>>) {
            unsafe {
                let n_a = node_x.as_ref().parent.unwrap();
                if n_a.as_ref().parent.is_some() {
                    let parent = (*n_a.as_ptr()).parent.unwrap();
                    let mut node_a_from_left = false;
                    if let Some(ref mut node_a) = (*parent.as_ptr()).left
                        && std::ptr::eq(node_a.as_ptr(), n_a.as_ptr())
                    {
                        node_a_from_left = true;
                    }
                    let node_a = if node_a_from_left {
                        (*parent.as_ptr()).left.unwrap()
                    } else {
                        (*parent.as_ptr()).right.unwrap()
                    };
                    let node_b = (*node_a.as_ptr()).left.unwrap();
                    let node_c = (*node_b.as_ptr()).right.unwrap();
                    let node_e = (*node_c.as_ptr()).right;
                    let node_d = (*node_c.as_ptr()).left.unwrap();
                    (*node_b.as_ptr()).right = Some(node_d);
                    (*node_b.as_ptr()).parent = Some(node_c);
                    (*node_d.as_ptr()).parent = Some(node_b);
                    (*node_a.as_ptr()).parent = Some(node_c);
                    (*node_a.as_ptr()).left = node_e;
                    if let Some(n_e) = node_e {
                        (*n_e.as_ptr()).parent = Some(node_a);
                    }
                    (*node_d.as_ptr()).is_red = false;
                    (*node_c.as_ptr()).left = Some(node_b);
                    (*node_c.as_ptr()).right = Some(node_a);
                    (*node_c.as_ptr()).parent = Some(parent);
                    if node_a_from_left {
                        (*parent.as_ptr()).left = Some(node_c);
                    } else {
                        (*parent.as_ptr()).right = Some(node_c);
                    }
                } else {
                    // node_a is root
                    if let Some(fixed_head) = self.fixed_head {
                        let node_a = (*fixed_head.as_ptr()).left.unwrap();
                        let node_b = (*node_a.as_ptr()).left.unwrap();
                        let node_c = (*node_b.as_ptr()).right.unwrap();
                        let node_e = (*node_c.as_ptr()).right;
                        let node_d = (*node_c.as_ptr()).left.unwrap();
                        (*node_b.as_ptr()).right = Some(node_d);
                        (*node_b.as_ptr()).parent = Some(node_c);
                        (*node_d.as_ptr()).parent = Some(node_b);
                        (*node_a.as_ptr()).parent = Some(node_c);
                        (*node_a.as_ptr()).left = node_e;
                        if let Some(n_e) = node_e {
                            (*n_e.as_ptr()).parent = Some(node_a);
                        }
                        (*node_d.as_ptr()).is_red = false;
                        (*node_c.as_ptr()).left = Some(node_b);
                        (*node_c.as_ptr()).right = Some(node_a);
                        (*node_c.as_ptr()).parent = None;
                        (*fixed_head.as_ptr()).left = Some(node_c);
                    }
                }
            }
        }

        /// 2.2.2 remove black X
        ///
        /// ```text
        ///    A            B
        ///  // \            \
        ///  B    X   =>       A
        ///  \               //
        ///   C             C
        /// ```
        unsafe fn remove_black_leaf_2_2_2_balancing(&mut self, node_x: &NonNull<Node<T>>) {
            unsafe {
                let n_a = node_x.as_ref().parent.unwrap();
                if n_a.as_ref().parent.is_some() {
                    let parent = (*n_a.as_ptr()).parent.unwrap();
                    let mut node_a_from_left = false;
                    if let Some(ref mut node_a) = (*parent.as_ptr()).left
                        && std::ptr::eq(node_a.as_ptr(), n_a.as_ptr())
                    {
                        node_a_from_left = true;
                    }
                    let node_a = if node_a_from_left {
                        (*parent.as_ptr()).left.unwrap()
                    } else {
                        (*parent.as_ptr()).right.unwrap()
                    };
                    let node_b = (*node_a.as_ptr()).left.unwrap();
                    (*node_b.as_ptr()).is_red = false;
                    (*node_b.as_ptr()).parent = Some(parent);
                    let node_c = (*node_b.as_ptr()).right.unwrap();
                    (*node_c.as_ptr()).is_red = true;
                    (*node_b.as_ptr()).right = Some(node_a);
                    (*node_a.as_ptr()).left = Some(node_c);
                    (*node_c.as_ptr()).parent = Some(node_a);
                    (*node_a.as_ptr()).parent = Some(node_b);
                    if node_a_from_left {
                        (*parent.as_ptr()).left = Some(node_b);
                    } else {
                        (*parent.as_ptr()).right = Some(node_b);
                    }
                } else {
                    // node_a is root
                    if let Some(fixed_head) = self.fixed_head {
                        let node_a = (*fixed_head.as_ptr()).left.unwrap();
                        let node_b = (*node_a.as_ptr()).left.unwrap();
                        (*node_b.as_ptr()).is_red = false;
                        (*node_b.as_ptr()).parent = None;
                        let node_c = (*node_b.as_ptr()).right.unwrap();
                        (*node_c.as_ptr()).is_red = true;
                        (*node_b.as_ptr()).right = Some(node_a);
                        (*node_a.as_ptr()).left = Some(node_c);
                        (*node_c.as_ptr()).parent = Some(node_a);
                        (*node_a.as_ptr()).parent = Some(node_b);
                        (*fixed_head.as_ptr()).left = Some(node_b);
                    }
                }
            }
        }

        /// 2.3.1.1 remove black X
        ///
        /// ```text
        ///      A           B
        ///     / \         / \
        ///    B   X  =>   D   A
        ///   // \            /
        ///  D    C          C
        /// ```
        unsafe fn remove_black_leaf_2_3_1_1_balancing(&mut self, node_x: &NonNull<Node<T>>) {
            unsafe {
                let node_a = (*node_x.as_ptr()).parent.unwrap();
                if let Some(parent) = (*node_a.as_ptr()).parent {
                    let node_b = (*node_a.as_ptr()).left.unwrap();
                    let node_c = (*node_b.as_ptr()).right;
                    let node_d = (*node_b.as_ptr()).left.unwrap();
                    (*node_d.as_ptr()).is_red = false;
                    let mut node_a_from_left = false;
                    if let Some(p_node_a) = (*parent.as_ptr()).left
                        && std::ptr::eq(p_node_a.as_ptr(), node_a.as_ptr())
                    {
                        node_a_from_left = true;
                    }
                    (*node_b.as_ptr()).parent = Some(parent);
                    (*node_b.as_ptr()).right = Some(node_a);
                    (*node_a.as_ptr()).parent = Some(node_b);
                    (*node_a.as_ptr()).left = node_c;
                    if let Some(n_c) = node_c {
                        (*n_c.as_ptr()).parent = Some(node_a);
                    }
                    if node_a_from_left {
                        (*parent.as_ptr()).left = Some(node_b);
                    } else {
                        (*parent.as_ptr()).right = Some(node_b);
                    }
                } else {
                    // node_a is root
                    if let Some(fixed_head) = self.fixed_head {
                        let node_a = (*fixed_head.as_ptr()).left.unwrap();
                        let node_b = (*node_a.as_ptr()).left.unwrap();
                        let node_c = (*node_b.as_ptr()).right;
                        let node_d = (*node_b.as_ptr()).left.unwrap();
                        (*node_d.as_ptr()).is_red = false;
                        let node_b = (*node_a.as_ptr()).left.unwrap();
                        (*node_b.as_ptr()).parent = None;
                        (*node_b.as_ptr()).right = Some(node_a);
                        (*node_a.as_ptr()).parent = Some(node_b);
                        (*node_a.as_ptr()).left = node_c;
                        if let Some(n_c) = node_c {
                            (*n_c.as_ptr()).parent = Some(node_a);
                        }
                        (*fixed_head.as_ptr()).left = Some(node_b);
                    }
                }
            }
        }

        /// 2.3.1.2 remove black X
        ///
        /// ```text
        ///
        ///      A            D
        ///     / \         /   \
        ///    X   B  =>   A     B
        ///       //        \   /
        ///       D          C E
        ///      / \
        ///     C   E
        /// ```
        unsafe fn remove_black_leaf_2_3_1_2_balancing(&mut self, node_x: &NonNull<Node<T>>) {
            unsafe {
                let node_a = (*node_x.as_ptr()).parent.unwrap();
                if let Some(parent) = (*node_a.as_ptr()).parent {
                    let node_b = (*node_a.as_ptr()).right.unwrap();
                    let node_d = (*node_b.as_ptr()).left.unwrap();
                    let node_c = (*node_d.as_ptr()).left;
                    let node_e = (*node_d.as_ptr()).right;
                    (*node_d.as_ptr()).is_red = false;
                    let mut node_a_from_left = false;
                    if let Some(p_node_a) = (*parent.as_ptr()).left
                        && std::ptr::eq(p_node_a.as_ptr(), node_a.as_ptr())
                    {
                        node_a_from_left = true;
                    }
                    (*node_d.as_ptr()).parent = Some(parent);
                    (*node_d.as_ptr()).left = Some(node_a);
                    (*node_d.as_ptr()).right = Some(node_b);
                    (*node_a.as_ptr()).parent = Some(node_d);
                    (*node_b.as_ptr()).parent = Some(node_d);
                    (*node_a.as_ptr()).right = node_c;
                    if let Some(n_c) = node_c {
                        (*n_c.as_ptr()).parent = Some(node_a);
                    }
                    (*node_b.as_ptr()).left = node_e;
                    if let Some(n_e) = node_e {
                        (*n_e.as_ptr()).parent = Some(node_b);
                    }
                    if node_a_from_left {
                        (*parent.as_ptr()).left = Some(node_d);
                    } else {
                        (*parent.as_ptr()).right = Some(node_d);
                    }
                } else {
                    // node_a is root
                    if let Some(fixed_head) = self.fixed_head {
                        let node_a = (*fixed_head.as_ptr()).left.unwrap();
                        let node_b = (*node_a.as_ptr()).right.unwrap();
                        let node_d = (*node_b.as_ptr()).left.unwrap();
                        let node_c = (*node_d.as_ptr()).left;
                        let node_e = (*node_d.as_ptr()).right;
                        (*node_d.as_ptr()).is_red = false;
                        (*node_d.as_ptr()).parent = None;
                        (*node_d.as_ptr()).left = Some(node_a);
                        (*node_d.as_ptr()).right = Some(node_b);
                        (*node_a.as_ptr()).parent = Some(node_d);
                        (*node_b.as_ptr()).parent = Some(node_d);
                        (*node_a.as_ptr()).right = node_c;
                        if let Some(n_c) = node_c {
                            (*n_c.as_ptr()).parent = Some(node_a);
                        }
                        (*node_b.as_ptr()).left = node_e;
                        if let Some(n_e) = node_e {
                            (*n_e.as_ptr()).parent = Some(node_b);
                        }
                        (*fixed_head.as_ptr()).left = Some(node_d);
                    }
                }
            }
        }

        /// 2.3.2.1 remove black X
        ///
        /// ```text
        ///            P           P
        ///            |           |
        ///            A           A
        ///           / \   =>    //   => next check node A
        ///          B   X       B
        ///
        /// ```
        unsafe fn remove_black_leaf_2_3_2_1_balancing(
            &mut self,
            node_x: &NonNull<Node<T>>,
        ) -> NonNull<Node<T>> {
            unsafe {
                let node_a = (*node_x.as_ptr()).parent.unwrap();
                let node_b = (*node_a.as_ptr()).left.unwrap();
                (*node_b.as_ptr()).is_red = true;
                node_a
            }
        }

        /// 2.3.2.2 remove black X
        ///
        /// ```text
        ///              A            B
        ///             / \   =>    // \    =>  next check node B
        ///            X   B       A    D
        ///               / \       \
        ///              C   D       C
        /// ```
        unsafe fn remove_black_leaf_2_3_2_2_balancing(
            &mut self,
            node_x: &NonNull<Node<T>>,
        ) -> NonNull<Node<T>> {
            unsafe {
                let node_a = (*node_x.as_ptr()).parent.unwrap();
                (*node_a.as_ptr()).is_red = true;
                if let Some(parent) = (*node_a.as_ptr()).parent {
                    let node_b = (*node_a.as_ptr()).right.unwrap();
                    let node_c = (*node_b.as_ptr()).left;
                    let node_d = (*node_b.as_ptr()).right;
                    let mut node_a_from_left = false;
                    if let Some(p_node_a) = (*parent.as_ptr()).left
                        && std::ptr::eq(p_node_a.as_ptr(), node_a.as_ptr())
                    {
                        node_a_from_left = true;
                    }
                    (*node_b.as_ptr()).parent = Some(parent);
                    (*node_a.as_ptr()).right = node_c;
                    if let Some(n_c) = node_c {
                        (*n_c.as_ptr()).parent = Some(node_a);
                    }
                    (*node_b.as_ptr()).right = node_d;
                    if let Some(n_d) = node_d {
                        (*n_d.as_ptr()).parent = Some(node_b);
                    }
                    (*node_b.as_ptr()).left = Some(node_a);
                    (*node_a.as_ptr()).parent = Some(node_b);
                    if node_a_from_left {
                        (*parent.as_ptr()).left = Some(node_b);
                    } else {
                        (*parent.as_ptr()).right = Some(node_b);
                    }
                    node_b
                } else {
                    // node_a is root
                    if let Some(fixed_head) = self.fixed_head {
                        let node_a = (*fixed_head.as_ptr()).left.unwrap();
                        (*node_a.as_ptr()).is_red = true;
                        let node_b = (*node_a.as_ptr()).right.unwrap();
                        let node_c = (*node_b.as_ptr()).left;
                        let node_d = (*node_b.as_ptr()).right;
                        (*node_b.as_ptr()).parent = None;
                        (*node_a.as_ptr()).right = node_c;
                        if let Some(n_c) = node_c {
                            (*n_c.as_ptr()).parent = Some(node_a);
                        }
                        (*node_b.as_ptr()).right = node_d;
                        if let Some(n_d) = node_d {
                            (*n_d.as_ptr()).parent = Some(node_b);
                        }
                        (*node_b.as_ptr()).left = Some(node_a);
                        (*node_a.as_ptr()).parent = Some(node_b);
                        (*fixed_head.as_ptr()).left = Some(node_b);
                    }
                    self.get_root().unwrap()
                }
            }
        }

        unsafe fn remove_node(&mut self, node: NonNull<Node<T>>) -> bool {
            unsafe {
                match self.operation_remove(&node) {
                    OperationRemove::RedLeaf => {
                        // option 1.0.0
                        //
                        // ```text
                        //
                        //  P
                        //  ||
                        //  X
                        //
                        // ```

                        self.remove_leaf(node)
                    }
                    OperationRemove::BlackLeaf => {
                        // option 2 black leaf
                        self.remove_black_leaf(node)
                    }
                    OperationRemove::NodeWithChildren => {
                        // option 4.0.0
                        // ```text
                        //        X
                        //     /      \
                        //    L        R
                        //   / \      / \
                        // ...  C    L
                        //          /
                        //         C
                        //        ...
                        //
                        // ```
                        /*
                            The node has two children.

                            We take the predecessor:
                            the maximal node of the left subtree.

                            We only change the values,
                            then we delete the predecessor as a regular node.
                        */

                        let predecessor = self.find_max(node.as_ref().left.unwrap());

                        std::mem::swap(
                            &mut (*node.as_ptr()).value,
                            &mut (*predecessor.as_ptr()).value,
                        );

                        self.remove_node(predecessor)
                    }
                    OperationRemove::BlackNodeWithRedLeaf => {
                        // option 3.0.0
                        // ```text
                        //  X
                        // //
                        // A
                        // ```
                        let red_left = (*node.as_ptr()).left.unwrap();
                        std::mem::swap(&mut (*node.as_ptr()).value, &mut (*red_left.as_ptr()).value);
                        self.remove_leaf(red_left)
                    }
                }
            }
        }

        unsafe fn find_max(&self, node: NonNull<Node<T>>) -> NonNull<Node<T>> {
            unsafe {
                if node.as_ref().right.is_some() {
                    self.find_max(node.as_ref().right.unwrap())
                } else {
                    node
                }
            }
        }

        unsafe fn find_min(&self, node: NonNull<Node<T>>) -> NonNull<Node<T>> {
            unsafe {
                if node.as_ref().left.is_some() {
                    self.find_min(node.as_ref().left.unwrap())
                } else {
                    node
                }
            }
        }

        unsafe fn remove_leaf(&mut self, node: NonNull<Node<T>>) -> bool {
            unsafe {
                if let Some(mut parent) = node.as_ref().parent {
                    if let Some(ref mut left) = parent.as_mut().left {
                        if std::ptr::eq(left.as_ptr(), node.as_ptr()) {
                            parent.as_mut().left = None;
                        } else {
                            parent.as_mut().right = None;
                        }
                    } else {
                        parent.as_mut().right = None;
                    }
                }
                let _ = Box::from_raw(node.as_ptr());
                true
            }
        }

        unsafe fn remove_tree(&mut self, node: Link<T>) {
            unsafe {
                if let Some(node) = node {
                    self.remove_tree(node.as_ref().left);
                    self.remove_tree(node.as_ref().right);
                    if self.remove_leaf(node) {
                        assert!(self.count > 0);
                        self.count -= 1;
                    }
                }
            }
        }

        /// Rotate left and Rotate right and Flip color
        ///
        /// ```text
        ///             |              ||
        ///             P              C
        ///           //  \          /   \
        ///          A     F        A     P
        ///         / \\      =>   / \   / \
        ///        B   C          B   E D   F
        ///            / \
        ///           E   D
        /// ```
        unsafe fn rotate_left_right_flip_color(&mut self, node_a: NonNull<Node<T>>) -> Link<T> {
            unsafe {
                let node_p = (*node_a.as_ptr()).parent.unwrap();
                if let Some(parent) = (*node_p.as_ptr()).parent {
                    let mut node_p_from_left = false;
                    if let Some(p_node_p) = (*parent.as_ptr()).left
                        && std::ptr::eq(p_node_p.as_ptr(), node_p.as_ptr())
                    {
                        node_p_from_left = true;
                    }
                    let node_p = if node_p_from_left {
                        (*parent.as_ptr()).left.unwrap()
                    } else {
                        (*parent.as_ptr()).right.unwrap()
                    };
                    (*node_a.as_ptr()).is_red = false;
                    let node_c = (*node_a.as_ptr()).right.unwrap();
                    (*node_c.as_ptr()).is_red = false;
                    let node_e = (*node_c.as_ptr()).left;
                    let node_d = (*node_c.as_ptr()).right;
                    (*node_c.as_ptr()).is_red = true;
                    (*node_c.as_ptr()).parent = Some(parent);
                    (*node_c.as_ptr()).left = Some(node_a);
                    (*node_a.as_ptr()).parent = Some(node_c);
                    (*node_c.as_ptr()).right = Some(node_p);
                    (*node_p.as_ptr()).parent = Some(node_c);
                    (*node_p.as_ptr()).left = node_d;
                    if let Some(n_d) = node_d {
                        (*n_d.as_ptr()).parent = Some(node_p);
                    }
                    (*node_a.as_ptr()).right = node_e;
                    if let Some(n_e) = node_e {
                        (*n_e.as_ptr()).parent = Some(node_a);
                    }
                    if node_p_from_left {
                        (*parent.as_ptr()).left = Some(node_c);
                    } else {
                        (*parent.as_ptr()).right = Some(node_c);
                    }
                    Some(parent)
                } else {
                    let fixed_head = self.fixed_head.unwrap();
                    let node_p = (*fixed_head.as_ptr()).left.unwrap();

                    let node_a = (*node_p.as_ptr()).left.unwrap();
                    (*node_a.as_ptr()).is_red = false;
                    let node_c = (*node_a.as_ptr()).right.unwrap();
                    (*node_c.as_ptr()).is_red = false;
                    let node_e = (*node_c.as_ptr()).left;
                    let node_d = (*node_c.as_ptr()).right;
                    (*node_c.as_ptr()).is_red = false;
                    (*node_c.as_ptr()).parent = None;
                    (*node_c.as_ptr()).left = Some(node_a);
                    (*node_a.as_ptr()).parent = Some(node_c);
                    (*node_c.as_ptr()).right = Some(node_p);
                    (*node_p.as_ptr()).parent = Some(node_c);
                    (*node_p.as_ptr()).left = node_d;
                    if let Some(n_d) = node_d {
                        (*n_d.as_ptr()).parent = Some(node_p);
                    }
                    (*node_a.as_ptr()).right = node_e;
                    if let Some(n_e) = node_e {
                        (*n_e.as_ptr()).parent = Some(node_a);
                    }
                    (*fixed_head.as_ptr()).left = Some(node_c);
                    (*fixed_head.as_ptr()).left
                }
            }
        }

        /// Rotate left without parent
        /// A is root
        ///
        /// ```text
        ///             A                  C
        ///            / \\               //\
        ///           B    C     =>      A   D
        ///               / \           / \
        ///              E   D         B   E
        ///
        /// ```
        ///
        /// Rotate left  with parent
        ///
        /// ```text
        ///             P                  P
        ///             |                  |
        ///             A                  C
        ///            / \\               //\
        ///           B    C     =>      A   D
        ///               / \           / \
        ///              E   D         B   E
        ///
        /// ```
        unsafe fn rotate_left(&mut self, node_a: NonNull<Node<T>>) -> Link<T> {
            unsafe {
                if let Some(parent) = (*node_a.as_ptr()).parent {
                    let mut node_a_from_left = false;
                    if let Some(p_node_a) = (*parent.as_ptr()).left
                        && std::ptr::eq(p_node_a.as_ptr(), node_a.as_ptr())
                    {
                        node_a_from_left = true;
                    }
                    let node_a = if node_a_from_left {
                        (*parent.as_ptr()).left.unwrap()
                    } else {
                        (*parent.as_ptr()).right.unwrap()
                    };
                    let node_c = (*node_a.as_ptr()).right.unwrap();
                    (*node_c.as_ptr()).is_red = (*node_a.as_ptr()).is_red;
                    (*node_a.as_ptr()).is_red = true;
                    (*node_c.as_ptr()).parent = Some(parent);
                    if node_c.as_ref().left.is_some() {
                        let mut node_e = (*node_c.as_ptr()).left;
                        if let Some(e) = &mut node_e {
                            (*e.as_ptr()).parent = Some(node_a);
                        }
                        (*node_a.as_ptr()).right = node_e;
                    } else {
                        (*node_a.as_ptr()).right = None;
                    }
                    (*node_c.as_ptr()).left = Some(node_a);
                    (*node_a.as_ptr()).parent = Some(node_c);
                    if node_a_from_left {
                        (*parent.as_ptr()).left = Some(node_c);
                        (*parent.as_ptr()).left
                    } else {
                        (*parent.as_ptr()).right = Some(node_c);
                        (*parent.as_ptr()).right
                    }
                } else {
                    let fixed_head = self.fixed_head.unwrap();
                    let node_a = (*fixed_head.as_ptr()).left.unwrap();
                    let node_c = (*node_a.as_ptr()).right.unwrap();
                    (*node_c.as_ptr()).is_red = (*node_a.as_ptr()).is_red;
                    (*node_a.as_ptr()).is_red = true;
                    if node_c.as_ref().left.is_some() {
                        let mut node_e = (*node_c.as_ptr()).left;
                        if let Some(e) = &mut node_e {
                            (*e.as_ptr()).parent = Some(node_a);
                        }
                        (*node_a.as_ptr()).right = node_e;
                    } else {
                        (*node_a.as_ptr()).right = None;
                    }
                    (*node_c.as_ptr()).left = Some(node_a);
                    (*node_a.as_ptr()).parent = Some(node_c);
                    (*node_c.as_ptr()).parent = None;
                    (*fixed_head.as_ptr()).left = Some(node_c);
                    (*fixed_head.as_ptr()).left
                }
            }
        }

        /// Rotate right without parent
        /// A is root
        ///
        /// ```text
        ///              A               B
        ///            // \             / \\
        ///            B   C     =>    E    A
        ///          // \                  / \
        ///         E    D                D   C
        /// ```
        ///
        /// Rotate right with parent
        ///
        /// ```text
        ///                P               P
        ///                |               |
        ///                A               B
        ///              // \             / \\
        ///              B   C     =>    E    A
        ///            // \                  / \
        ///           E    D                D   C
        ///
        /// ```
        unsafe fn rotate_right(&mut self, node_a: NonNull<Node<T>>) -> Link<T> {
            unsafe {
                if let Some(parent) = (*node_a.as_ptr()).parent {
                    let mut node_a_from_left = false;
                    if let Some(p_node_a) = (*parent.as_ptr()).left
                        && std::ptr::eq(p_node_a.as_ptr(), node_a.as_ptr())
                    {
                        node_a_from_left = true;
                    }
                    let node_a = if node_a_from_left {
                        (*parent.as_ptr()).left.unwrap()
                    } else {
                        (*parent.as_ptr()).right.unwrap()
                    };
                    let node_b = (*node_a.as_ptr()).left.unwrap();
                    (*node_b.as_ptr()).parent = Some(parent);
                    (*node_b.as_ptr()).is_red = (*node_a.as_ptr()).is_red;
                    (*node_a.as_ptr()).is_red = true;
                    if node_b.as_ref().right.is_some() {
                        let mut node_d = (*node_b.as_ptr()).right;
                        if let Some(d) = &mut node_d {
                            (*d.as_ptr()).parent = Some(node_a);
                        }
                        (*node_a.as_ptr()).left = node_d;
                    } else {
                        (*node_a.as_ptr()).left = None;
                    }
                    (*node_b.as_ptr()).right = Some(node_a);
                    (*node_a.as_ptr()).parent = Some(node_b);
                    if node_a_from_left {
                        (*parent.as_ptr()).left = Some(node_b);
                        (*parent.as_ptr()).left
                    } else {
                        (*parent.as_ptr()).right = Some(node_b);
                        (*parent.as_ptr()).right
                    }
                } else {
                    let fixed_head = self.fixed_head.unwrap();
                    let node_a = (*fixed_head.as_ptr()).left.unwrap();
                    let node_b = (*node_a.as_ptr()).left.unwrap();
                    (*node_b.as_ptr()).is_red = (*node_a.as_ptr()).is_red;
                    (*node_a.as_ptr()).is_red = true;
                    if node_b.as_ref().right.is_some() {
                        let mut node_d = (*node_b.as_ptr()).right;
                        if let Some(d) = &mut node_d {
                            (*d.as_ptr()).parent = Some(node_a);
                        }
                        (*node_a.as_ptr()).left = node_d;
                    } else {
                        (*node_a.as_ptr()).left = None;
                    }
                    (*node_b.as_ptr()).right = Some(node_a);
                    (*node_a.as_ptr()).parent = Some(node_b);
                    (*node_b.as_ptr()).parent = None;
                    (*fixed_head.as_ptr()).left = Some(node_b);
                    (*fixed_head.as_ptr()).left
                }
            }
        }

        /// Flip color
        ///
        /// ```text
        ///             |          ||
        ///             A    =>    A
        ///           // \\       / \
        ///          B    C      B   C
        ///
        /// ```
        unsafe fn flip_colors(&mut self, mut node: NonNull<Node<T>>) {
            unsafe {
                if node.as_ref().left.is_some() && node.as_ref().right.is_some() {
                    if let Some(ref mut left) = node.as_mut().left {
                        left.as_mut().is_red = false;
                    }
                    if let Some(ref mut right) = node.as_mut().right {
                        right.as_mut().is_red = false;
                    }
                    node.as_mut().is_red = true;

                    if (*node.as_ptr()).parent.is_none() {
                        node.as_mut().is_red = false;
                    }
                }
            }
        }

        unsafe fn check_put_balancing(&mut self, node: NonNull<Node<T>>) -> OperationPut {
            unsafe {
                if node.as_ref().right.is_some() {
                    let r = node.as_ref().right.unwrap();
                    if node.as_ref().left.is_some() && !node.as_ref().is_red {
                        let l = node.as_ref().left.unwrap();
                        if l.as_ref().is_red && r.as_ref().is_red {
                            return OperationPut::FlipColors;
                        }
                    }
                    if r.as_ref().is_red {
                        return OperationPut::Left;
                    }
                }
                if node.as_ref().is_red && node.as_ref().left.is_some() {
                    let l = node.as_ref().left.unwrap();
                    if l.as_ref().is_red {
                        return OperationPut::Right;
                    }
                }
                OperationPut::Nothing
            }
        }

        unsafe fn put_balancing(&mut self, next: NonNull<Node<T>>) {
            unsafe {
                let mut next = next;
                loop {
                    match self.check_put_balancing(next) {
                        OperationPut::Left => {
                            if (*next.as_ptr()).is_red {
                                if let Some(n) = self.rotate_left_right_flip_color(next) {
                                    next = n;
                                }
                            } else {
                                if let Some(n) = self.rotate_left(next) {
                                    next = n;
                                }
                            }
                        }
                        OperationPut::Right => {
                            if (*next.as_ptr()).parent.is_some() {
                                let node_a = (*next.as_ptr()).parent.unwrap();
                                if let Some(n) = self.rotate_right(node_a) {
                                    next = n;
                                }
                            }
                        }
                        OperationPut::FlipColors => {
                            self.flip_colors(next);
                            if (*next.as_ptr()).parent.is_some() {
                                next = (*next.as_ptr()).parent.unwrap();
                            } else {
                                break;
                            }
                        }
                        OperationPut::Nothing => {
                            break;
                        }
                    }
                }
            }
        }

        unsafe fn find_put_parent_candidate(&mut self, parent: Link<T>, elem: &T) -> Link<T> {
            unsafe {
                if let Some(parent) = parent {
                    match elem.cmp(&parent.as_ref().value) {
                        Ordering::Equal => None,
                        Ordering::Less => {
                            if (*parent.as_ptr()).left.is_some() {
                                self.find_put_parent_candidate((*parent.as_ptr()).left, elem)
                            } else {
                                Some(parent)
                            }
                        }
                        Ordering::Greater => {
                            if (*parent.as_ptr()).right.is_some() {
                                self.find_put_parent_candidate((*parent.as_ptr()).right, elem)
                            } else {
                                Some(parent)
                            }
                        }
                    }
                } else {
                    parent
                }
            }
        }

        unsafe fn attach_node(&mut self, parent: NonNull<Node<T>>, elem: T) -> bool {
            unsafe {
                match elem.cmp(&parent.as_ref().value) {
                    Ordering::Equal => false,
                    Ordering::Less => {
                        (*parent.as_ptr()).left = Node::new_red(elem, parent);
                        true
                    }
                    Ordering::Greater => {
                        (*parent.as_ptr()).right = Node::new_red(elem, parent);
                        true
                    }
                }
            }
        }

        /// Returns the default iterator over the tree.
        ///
        /// The default traversal is in-order (`LNR`), so values are yielded in
        /// ascending order.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([3, 1, 2]);
        ///
        /// let values: Vec<i32> = tree.iter().copied().collect();
        ///
        /// assert_eq!(values, vec![1, 2, 3]);
        /// ```
        pub fn iter(&self) -> IterInOrder<'_, T> {
            self.iter_inorder()
        }

        /// Returns an in-order (`LNR`) iterator.
        ///
        /// Values are yielded in ascending order.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([3, 1, 2]);
        ///
        /// assert_eq!(
        ///     tree.iter_inorder().copied().collect::<Vec<_>>(),
        ///     vec![1, 2, 3]
        /// );
        /// ```
        pub fn iter_inorder(&self) -> IterInOrder<'_, T> {
            unsafe { IterInOrder::new(leftmost_child_in_order(self.get_root()), self.count) }
        }

        /// Returns a reverse in-order (`RNL`) iterator.
        ///
        /// Values are yielded in descending order.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([3, 1, 2]);
        ///
        /// assert_eq!(
        ///     tree.iter_reverse_inorder().copied().collect::<Vec<_>>(),
        ///     vec![3, 2, 1]
        /// );
        /// ```
        pub fn iter_reverse_inorder(&self) -> IterReverseInOrder<'_, T> {
            unsafe {
                IterReverseInOrder::new(
                    rightmost_child_reverse_in_order(self.get_root()),
                    self.count,
                )
            }
        }

        /// Returns a pre-order (`NLR`) iterator.
        ///
        /// The current node is visited before its left and right subtrees.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([4, 2, 6, 1, 3, 5, 7]);
        ///
        /// let values: Vec<i32> = tree.iter_preorder().copied().collect();
        ///
        /// assert_eq!(values.len(), tree.len());
        /// ```
        pub fn iter_preorder(&self) -> IterPreOrder<'_, T> {
            IterPreOrder::new(self.get_root(), self.count)
        }

        /// Returns a post-order (`LRN`) iterator.
        ///
        /// The left and right subtrees are visited before the current node.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([4, 2, 6, 1, 3, 5, 7]);
        ///
        /// let values: Vec<i32> = tree.iter_postorder().copied().collect();
        ///
        /// assert_eq!(values.len(), tree.len());
        /// ```
        pub fn iter_postorder(&self) -> IterPostOrder<'_, T> {
            unsafe {
                let first = self.get_root().map(|root| leaf_post_order(root));
                IterPostOrder::new(first, self.count)
            }
        }

        /// Returns all values in level-order traversal.
        ///
        /// Nodes are visited level by level, starting from the root.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([4, 2, 6, 1, 3, 5, 7]);
        ///
        /// let values = tree.iter_level_order();
        ///
        /// assert_eq!(values.len(), tree.len());
        /// ```
        pub fn iter_level_order(&self) -> Vec<&T> {
            let mut ret: Vec<&T> = vec![];
            if let Some(root) = self.get_root() {
                iter_level_order_impl(root, &mut ret);
            }
            ret
        }
    }

    impl<'a, T: Ord + Default> std::iter::IntoIterator for &'a RedBlackTree<T> {
        type IntoIter = IterInOrder<'a, T>;
        type Item = &'a T;

        fn into_iter(self) -> Self::IntoIter {
            self.iter()
        }
    }

    impl<T: Ord + Default> Drop for RedBlackTree<T> {
        fn drop(&mut self) {
            unsafe {
                if let Some(fixed_head) = self.fixed_head {
                    self.remove_tree((*fixed_head.as_ptr()).left);
                    let _ = Box::from_raw(fixed_head.as_ptr());
                }
                self.fixed_head = None;
            }
        }
    }

    fn find_node<T: Ord>(fromnode: Link<T>, value: &T) -> Link<T> {
        unsafe {
            if let Some(fromnode) = fromnode {
                match value.cmp(&(*fromnode.as_ptr()).value) {
                    Ordering::Equal => Some(fromnode),
                    Ordering::Less => find_node((*fromnode.as_ptr()).left, value),
                    Ordering::Greater => find_node((*fromnode.as_ptr()).right, value),
                }
            } else {
                fromnode
            }
        }
    }

    fn helper_display_tree<T: Display>(node: NonNull<Node<T>>) -> String {
        unsafe {
            let mut s: String = "".into();
            let color = if (*node.as_ptr()).is_red {
                "[color=\"red\"]"
            } else {
                "[color=\"black\"]"
            };

            if let Some(left) = (*node.as_ptr()).left {
                s.push_str(&format!(
                    "\t{n1}->{n2} {color1}; {n1} {color1}; {n2} {color2};\n",
                    n1 = (*node.as_ptr()).value,
                    n2 = (*left.as_ptr()).value,
                    color1 = color,
                    color2 = if (*left.as_ptr()).is_red {
                        "[color=\"red\"]"
                    } else {
                        "[color=\"black\"]"
                    },
                ));
                s.push_str(&helper_display_tree(left));
            } else if (*node.as_ptr()).right.is_some() {
                s.push_str(&format!(
                    "\t{n1}->node_null_{n1} [color=\"grey\"]; {n1} {color1};\n",
                    n1 = (*node.as_ptr()).value,
                    color1 = color
                ));
                s.push_str(&format!(
                    "\tnode_null_{n1}[label=\"null\"]\n",
                    n1 = (*node.as_ptr()).value
                ));
            }

            if let Some(right) = (*node.as_ptr()).right {
                s.push_str(&format!(
                    "\t{n1}->{n2} {color1}; {n1} {color1}; {n2} {color2};\n",
                    n1 = (*node.as_ptr()).value,
                    n2 = (*right.as_ptr()).value,
                    color2 = if (*right.as_ptr()).is_red {
                        "[color=\"red\"]"
                    } else {
                        "[color=\"black\"]"
                    },
                    color1 = color
                ));
                s.push_str(&helper_display_tree(right));
            } else {
                s.push_str(&format!(
                    "\t{n1}->node_null_{n1} [color=\"grey\"]; {n1} {color1};\n",
                    n1 = (*node.as_ptr()).value,
                    color1 = color
                ));
                s.push_str(&format!(
                    "\tnode_null_{}[label=\"null\"]\n",
                    (*node.as_ptr()).value
                ));
            }
            s
        }
    }

    impl<T: Ord + Default> Default for RedBlackTree<T> {
        fn default() -> Self {
            Self::new()
        }
    }

    impl<T: Ord + Default + Clone> Clone for RedBlackTree<T> {
        fn clone(&self) -> Self {
            let mut new_list = Self::new();
            for value in self {
                new_list.insert(value.clone());
            }
            new_list
        }
    }

    impl<T: Ord + Default> Extend<T> for RedBlackTree<T> {
        fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
            for value in iter {
                self.insert(value);
            }
        }
    }

    impl<T: Ord + Default> FromIterator<T> for RedBlackTree<T> {
        fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
            let mut list = Self::new();
            list.extend(iter);
            list
        }
    }

    impl<T: Ord + Default + Debug> Debug for RedBlackTree<T> {
        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
            f.debug_list().entries(self).finish()
        }
    }

    impl<T: Ord + Default> PartialEq for RedBlackTree<T> {
        fn eq(&self, other: &Self) -> bool {
            self.len() == other.len() && self.iter_inorder().eq(other.iter_inorder())
        }
    }

    impl<T: Ord + Default> Eq for RedBlackTree<T> {}

    impl<T: Ord + Default> PartialOrd for RedBlackTree<T> {
        fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
            Some(self.cmp(other))
        }
    }

    impl<T: Ord + Default> Ord for RedBlackTree<T> {
        fn cmp(&self, other: &Self) -> Ordering {
            self.iter_inorder().cmp(other.iter_inorder())
        }
    }

    impl<T: Ord + Default + std::hash::Hash> std::hash::Hash for RedBlackTree<T> {
        fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
            self.len().hash(state);
            for item in self {
                item.hash(state);
            }
        }
    }
}

4. Ближайшее значение (Lower bound / Upper bound)

lower_bound и upper_bound нужны, когда точного значения может не быть, но нужно найти ближайшую подходящую границу.

  • lower_bound(x) → первый элемент >= x
  • upper_bound(x) → первый элемент > x

Это полезно для расписаний, цен, временных событий, bucket boundaries.

Например для расписания, пассажир пришёл на станцию в 10:20:

  • найти первый поезд не раньше 10:20
  • найти первый поезд строго позже 10:20
fn main() {
    let mut schedule = RedBlackTree::new();
    // расписание всех поездов
    for time in [800, 930, 1100, 1315, 1540, 1800] {
        schedule.insert(time);
    }

    let arrival = 1020;

    println!(
        "Ближайший поезд не раньше {}: {:?}",
        arrival,
        schedule.lower_bound(&arrival)
    );

    println!(
        "Первый поезд строго позже {}: {:?}",
        arrival,
        schedule.upper_bound(&arrival)
    );
}














/// -------------------------------------------
/// Implementation RBT
/// -------------------------------------------


pub use tree::RedBlackTree;
pub use iter::{IterInOrder, Range};
pub use iter::IterPreOrder;
pub use iter::IterReverseInOrder;
pub use iter::IterPostOrder;
 
pub mod iter{
    use std::ptr::NonNull;

    use crate::node::{Link, Node};

    ///```text
    ///
    ///            4
    ///          /   \
    ///         2     9
    ///        / \   //\
    ///       1   3  7   10
    ///             / \
    ///            6   8
    ///```
    ///    Depth-First Search / Pre-order (NLR):     4, 2, 1, 3, 9, 7, 6, 8, 10
    ///    Depth-First Search / In-order (LNR):      1, 2, 3, 4, 6, 7, 8, 9, 10
    ///    Depth-First Search / Post-order (LRN):    1, 3, 2, 6, 8, 7, 10, 9, 4
    ///    Breadth-First Search / Level-order:       4, 2, 9, 1, 3, 7, 10, 6, 8 
    pub use dfs_in_order::{IterInOrder, Range};

    pub(crate) use dfs_in_order::{leftmost_child_in_order, successor_of_node_in_order};

    mod dfs_in_order {
        use super::{Link, Node, NonNull};
        use std::iter::FusedIterator;
        use std::marker::PhantomData;

        /// Returns the next node in an in-order (`LNR`) traversal.
        ///
        /// # Safety
        ///
        /// `node` must point to a live node that belongs to the current tree, and
        /// all parent/child links reachable from it must be valid.
        pub unsafe fn successor_of_node_in_order<T>(node: NonNull<Node<T>>) -> Link<T> {
            unsafe {
                if node.as_ref().right.is_some() {
                    // If a right subtree exists, the successor is its leftmost node.
                    leftmost_child_in_order(node.as_ref().right)
                } else {
                    // Otherwise, walk up through parent links until the current
                    // node is found in a left subtree.
                    parent_with_left(node)
                }
            }
        }

        /// Returns the leftmost node reachable from `node`.
        ///
        /// Returns `None` when `node` is `None`.
        ///
        /// # Safety
        ///
        /// Every pointer reachable through `left` links must refer to a live node.
        pub unsafe fn leftmost_child_in_order<T>(node: Link<T>) -> Link<T> {
            unsafe {
                if let Some(node) = node {
                    if node.as_ref().left.is_none() {
                        Some(node)
                    } else {
                        leftmost_child_in_order(node.as_ref().left)
                    }
                } else {
                    node
                }
            }
        }

        /// Walks up the parent chain until an ancestor is reached from its left child.
        ///
        /// # Safety
        ///
        /// `node` and all parent links traversed by this function must be valid.
        unsafe fn parent_with_left<T>(node: NonNull<Node<T>>) -> Link<T> {
            unsafe {
                let parent = node.as_ref().parent;
                if let Some(parent) = parent
                    && let Some(left) = parent.as_ref().left
                {
                    if std::ptr::eq(left.as_ptr(), node.as_ptr()) {
                        return Some(parent);
                    }
                    return parent_with_left(parent);
                }
                // No parent means that the root has been reached.
                None
            }
        }

        /// Iterator over a tree in in-order (`Left -> Node -> Right`, or `LNR`).
        ///
        /// For a binary search tree, this traversal yields values in ascending order.
        pub struct IterInOrder<'a, T> {
            current_node: Link<T>,
            count: usize,
            elem: Option<&'a T>,
            _boo: PhantomData<&'a T>,
        }

        impl<'a, T> IterInOrder<'a, T> {
            /// Creates an in-order iterator starting at `node`.
            pub(crate) fn new(node: Link<T>, count: usize) -> Self {
                Self {
                    current_node: node,
                    count,
                    elem: None,
                    _boo: PhantomData,
                }
            }
        }

        impl<'a, T> Iterator for IterInOrder<'a, T> {
            type Item = &'a T;

            fn next(&mut self) -> Option<Self::Item> {
                if self.count > 0 {
                    self.count -= 1;
                    if let Some(node) = self.current_node {
                        unsafe {
                            self.elem = Some(&node.as_ref().value);
                            self.current_node = successor_of_node_in_order(node);
                        }
                    } else {
                        self.elem = None;
                    }
                } else {
                    self.elem = None;
                }
                self.elem
            }

            fn size_hint(&self) -> (usize, Option<usize>) {
                (self.count, Some(self.count))
            }
        }

        impl<'a, T> ExactSizeIterator for IterInOrder<'a, T> {
            fn len(&self) -> usize {
                self.count
            }
        }

        impl<'a, T> FusedIterator for IterInOrder<'a, T> {}

        /// A lazy iterator over an inclusive range of values in a [`crate::RedBlackTree`].
        ///
        /// `Range` is created by [`crate::RedBlackTree::range`]. It yields references to
        /// values in ascending order, starting from the first value greater than or
        /// equal to the lower bound and stopping after the upper bound.
        ///
        /// The iterator does not allocate an intermediate collection. Values are
        /// produced one at a time as the iterator advances.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([1, 3, 5, 7, 9, 11]);
        ///
        /// let values: Vec<_> = tree
        ///     .range(&3, &9)
        ///     .copied()
        ///     .collect();
        ///
        /// assert_eq!(values, vec![3, 5, 7, 9]);
        /// ```
        ///
        /// The iterator can be combined with standard iterator adapters:
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend(1..=100);
        ///
        /// let values: Vec<_> = tree
        ///     .range(&20, &80)
        ///     .take(3)
        ///     .copied()
        ///     .collect();
        ///
        /// assert_eq!(values, vec![20, 21, 22]);
        /// ```
        pub struct Range<'a, T> {
            current_node: Link<T>,
            end_node: Link<T>,
            _marker: PhantomData<&'a T>,
        }

        impl<'a, T: Ord> Range<'a, T> {
            pub(crate) fn new(root: Link<T>, min: &T, max: &T) -> Self {
                if min > max {
                    return Self {
                        current_node: None,
                        end_node: None,
                        _marker: PhantomData,
                    };
                }

                unsafe {
                    let mut current = root;
                    let mut start: Link<T> = None;

                    // First node >= min.
                    while let Some(node) = current {
                        match node.as_ref().value.cmp(min) {
                            std::cmp::Ordering::Less => {
                                current = node.as_ref().right;
                            }

                            std::cmp::Ordering::Equal => {
                                start = Some(node);
                                break;
                            }

                            std::cmp::Ordering::Greater => {
                                start = Some(node);
                                current = node.as_ref().left;
                            }
                        }
                    }

                    current = root;

                    let mut end: Link<T> = None;

                    // First node > max.
                    while let Some(node) = current {
                        match node.as_ref().value.cmp(max) {
                            std::cmp::Ordering::Less | std::cmp::Ordering::Equal => {
                                current = node.as_ref().right;
                            }

                            std::cmp::Ordering::Greater => {
                                end = Some(node);
                                current = node.as_ref().left;
                            }
                        }
                    }

                    Self {
                        current_node: start,
                        end_node: end,
                        _marker: PhantomData,
                    }
                }
            }
        }

        impl<'a, T> Iterator for Range<'a, T> {
            type Item = &'a T;

            fn next(&mut self) -> Option<Self::Item> {
                let node = self.current_node?;

                if self.end_node == Some(node) {
                    self.current_node = None;
                    return None;
                }

                unsafe {
                    let value = &node.as_ref().value;

                    self.current_node = successor_of_node_in_order(node);

                    Some(value)
                }
            }
        }
    }

    pub use dfs_reverse_in_order::IterReverseInOrder;

    pub(crate) use dfs_reverse_in_order::{
        rightmost_child_reverse_in_order, successor_of_node_reverse_in_order,
    };

    mod dfs_reverse_in_order {
        use super::{Link, Node, NonNull};
        use std::marker::PhantomData;

        /// Returns the next node in reverse in-order (`Right -> Node -> Left`, or `RNL`).
        ///
        /// # Safety
        ///
        /// `node` must point to a live node that belongs to the current tree, and
        /// all parent/child links reachable from it must be valid.
        pub unsafe fn successor_of_node_reverse_in_order<T>(node: NonNull<Node<T>>) -> Link<T> {
            unsafe {
                if node.as_ref().left.is_some() {
                    // After the current node, descend into the left subtree and
                    // choose its rightmost node.
                    rightmost_child_reverse_in_order(node.as_ref().left)
                } else {
                    // Without a left subtree, walk upward until reaching an
                    // ancestor from its right subtree.
                    parent_with_right(node)
                }
            }
        }

        /// Returns the rightmost node reachable from `node`.
        ///
        /// Returns `None` when `node` is `None`.
        ///
        /// # Safety
        ///
        /// Every pointer reachable through `right` links must refer to a live node.
        pub unsafe fn rightmost_child_reverse_in_order<T>(node: Link<T>) -> Link<T> {
            unsafe {
                if let Some(node) = node {
                    if node.as_ref().right.is_none() {
                        Some(node)
                    } else {
                        rightmost_child_reverse_in_order(node.as_ref().right)
                    }
                } else {
                    None
                }
            }
        }

        /// Walks up the parent chain until an ancestor is reached from its right child.
        ///
        /// # Safety
        ///
        /// `node` and all parent links traversed by this function must be valid.
        unsafe fn parent_with_right<T>(node: NonNull<Node<T>>) -> Link<T> {
            unsafe {
                let parent = node.as_ref().parent;

                if let Some(parent) = parent
                    && let Some(right) = parent.as_ref().right
                {
                    if std::ptr::eq(right.as_ptr(), node.as_ptr()) {
                        return Some(parent);
                    }

                    return parent_with_right(parent);
                }

                None
            }
        }

        /// Iterator over a tree in reverse in-order (`Right -> Node -> Left`, or `RNL`).
        ///
        /// For a binary search tree, this traversal yields values in descending order.
        pub struct IterReverseInOrder<'a, T> {
            current_node: Link<T>,
            count: usize,
            elem: Option<&'a T>,
            _boo: PhantomData<&'a T>,
        }

        impl<'a, T> IterReverseInOrder<'a, T> {
            /// Creates a reverse in-order iterator starting at `node`.
            pub(crate) fn new(node: Link<T>, count: usize) -> Self {
                Self {
                    current_node: node,
                    count,
                    elem: None,
                    _boo: PhantomData,
                }
            }
        }

        impl<'a, T> Iterator for IterReverseInOrder<'a, T> {
            type Item = &'a T;

            fn next(&mut self) -> Option<Self::Item> {
                if self.count > 0 {
                    self.count -= 1;

                    if let Some(node) = self.current_node {
                        unsafe {
                            self.elem = Some(&node.as_ref().value);
                            self.current_node = successor_of_node_reverse_in_order(node);
                        }
                    } else {
                        self.elem = None;
                    }
                } else {
                    self.elem = None;
                }

                self.elem
            }

            fn size_hint(&self) -> (usize, Option<usize>) {
                (self.count, Some(self.count))
            }
        }
    }

    pub use dfs_pre_order::IterPreOrder;

    pub(crate) use dfs_pre_order::successor_of_node_pre_order;

    mod dfs_pre_order {
        use super::{Link, Node, NonNull};
        use std::marker::PhantomData;

        /// Returns the next node in a pre-order (`Node -> Left -> Right`, or `NLR`) traversal.
        ///
        /// # Safety
        ///
        /// `node` must point to a live node in the current tree and all traversed
        /// links must be valid.
        pub unsafe fn successor_of_node_pre_order<T>(node: NonNull<Node<T>>) -> Link<T> {
            unsafe {
                if let Some(node) = node.as_ref().left {
                    Some(node)
                } else if let Some(node) = node.as_ref().right {
                    Some(node)
                } else {
                    right_with_parent(node)
                }
            }
        }

        /// Finds the next right subtree by walking through parent links.
        ///
        /// # Safety
        ///
        /// `node` and all parent links traversed by this function must be valid.
        unsafe fn right_with_parent<T>(node: NonNull<Node<T>>) -> Link<T> {
            unsafe {
                if let Some(parent) = node.as_ref().parent {
                    next_right(Some(parent), node)
                } else {
                    None
                }
            }
        }

        /// Searches ancestors for the next unvisited right child.
        ///
        /// # Safety
        ///
        /// `child`, `node`, and all links traversed by this function must be valid.
        unsafe fn next_right<T>(node: Link<T>, child: NonNull<Node<T>>) -> Link<T> {
            unsafe {
                if let Some(n) = node {
                    if let Some(right) = n.as_ref().right {
                        if std::ptr::eq(right.as_ptr(), child.as_ptr()) {
                            next_right(n.as_ref().parent, n)
                        } else {
                            Some(right)
                        }
                    } else {
                        next_right(n.as_ref().parent, n)
                    }
                } else {
                    None
                }
            }
        }

        /// Iterator over a tree in pre-order (`Node -> Left -> Right`, or `NLR`).
        ///
        /// Pre-order traversal visits a node before either of its subtrees.
        pub struct IterPreOrder<'a, T> {
            current_node: Link<T>,
            count: usize,
            elem: Option<&'a T>,
            _boo: PhantomData<&'a T>,
        }

        impl<'a, T> IterPreOrder<'a, T> {
            /// Creates a pre-order iterator starting at `root`.
            pub(crate) fn new(root: Link<T>, count: usize) -> Self {
                Self {
                    current_node: root,
                    count,
                    elem: None,
                    _boo: PhantomData,
                }
            }
        }

        impl<'a, T> Iterator for IterPreOrder<'a, T> {
            type Item = &'a T;

            fn next(&mut self) -> Option<Self::Item> {
                if self.count > 0 {
                    self.count -= 1;
                    if let Some(node) = self.current_node {
                        unsafe {
                            self.elem = Some(&node.as_ref().value);
                            self.current_node = successor_of_node_pre_order(node);
                        }
                    } else {
                        self.elem = None;
                    }
                } else {
                    self.elem = None;
                }
                self.elem
            }

            fn size_hint(&self) -> (usize, Option<usize>) {
                (self.count, Some(self.count))
            }
        }
    }

    pub use dfs_post_order::IterPostOrder;

    pub(crate) use dfs_post_order::{leaf_post_order, successor_of_node_post_order};

    mod dfs_post_order {
        use super::{Link, Node, NonNull};
        use std::marker::PhantomData;

        /// Returns the next node in a post-order (`Left -> Right -> Node`, or `LRN`) traversal.
        ///
        /// # Safety
        ///
        /// `current_node` must point to a live node in the current tree and all
        /// traversed parent/child links must be valid.
        pub unsafe fn successor_of_node_post_order<T>(current_node: NonNull<Node<T>>) -> Link<T> {
            unsafe {
                if let Some(parent) = current_node.as_ref().parent {
                    if let Some(right) = parent.as_ref().right {
                        if std::ptr::eq(current_node.as_ptr(), right.as_ptr()) {
                            Some(parent)
                        } else {
                            Some(leaf_post_order(right))
                        }
                    } else {
                        Some(parent)
                    }
                } else {
                    None
                }
            }
        }

        /// Returns the first leaf visited by a post-order traversal starting at `node`.
        ///
        /// # Safety
        ///
        /// `node` must point to a live node and all descendant links traversed by
        /// this function must be valid.
        pub unsafe fn leaf_post_order<T>(node: NonNull<Node<T>>) -> NonNull<Node<T>> {
            unsafe {
                if let Some(left) = node.as_ref().left {
                    leaf_post_order(left)
                } else if let Some(right) = node.as_ref().right {
                    leaf_post_order(right)
                } else {
                    node
                }
            }
        }

        /// Iterator over a tree in post-order (`Left -> Right -> Node`, or `LRN`).
        ///
        /// Post-order traversal visits both subtrees before the current node.
        pub struct IterPostOrder<'a, T> {
            current_node: Link<T>,
            count: usize,
            _boo: PhantomData<&'a T>,
        }

        impl<'a, T> IterPostOrder<'a, T> {
            /// Creates a post-order iterator starting at the first post-order node.
            pub(crate) fn new(root: Link<T>, count: usize) -> Self {
                Self {
                    current_node: root,
                    count,
                    _boo: PhantomData,
                }
            }
        }

        impl<'a, T> Iterator for IterPostOrder<'a, T> {
            type Item = &'a T;

            fn next(&mut self) -> Option<Self::Item> {
                if self.count == 0 {
                    return None;
                }

                let node = self.current_node?;

                unsafe {
                    let value = &node.as_ref().value;
                    self.current_node = successor_of_node_post_order(node);
                    self.count -= 1;
                    Some(value)
                }
            }

            fn size_hint(&self) -> (usize, Option<usize>) {
                (self.count, Some(self.count))
            }
        }
    }

    /// Breadth-First Search
    mod bfs {
        use super::{Node, NonNull};
        use std::collections::VecDeque;

        /// Appends tree values to `ret` in breadth-first / level-order.
        pub fn iter_level_order_impl<T>(root: NonNull<Node<T>>, ret: &mut Vec<&T>) {
            let mut deque: VecDeque<NonNull<Node<T>>> = VecDeque::new();
            unsafe {
                deque.push_back(root);
                let mut node: NonNull<Node<T>>;
                while !deque.is_empty() {
                    node = deque.pop_front().unwrap();
                    ret.push(&node.as_ref().value);
                    if let Some(left) = node.as_ref().left {
                        deque.push_back(left);
                    }
                    if let Some(right) = node.as_ref().right {
                        deque.push_back(right);
                    }
                }
            }
        }
    }

    pub(crate) use bfs::iter_level_order_impl;
}

/// Internal node representation used by the Red-Black Tree.
///
/// Nodes are allocated on the heap and connected using [`NonNull`] pointers.
/// The tree owns the allocated nodes and is responsible for releasing them.
///
/// `Node` and [`Link`] are crate-private implementation details and are not
/// exposed through the public API.
pub mod node{

    use std::ptr::NonNull;

    /// A single node in the Red-Black Tree.
    ///
    /// Each node stores:
    ///
    /// - a link to its left child;
    /// - a link to its right child;
    /// - a link to its parent;
    /// - its Red-Black color;
    /// - the stored value.
    ///
    /// Tree links are represented by [`Link<T>`], which is an
    /// `Option<NonNull<Node<T>>>`.
    ///
    /// A `None` link represents the absence of a parent or child, while
    /// `Some(pointer)` refers to another allocated node.
    ///
    /// Memory ownership is managed by [`crate::RedBlackTree`]. The pointers stored
    /// here are non-owning links between nodes.
    #[derive(Debug)]
    pub(crate) struct Node<T> {
        /// Left child of this node.
        pub(crate) left: Link<T>,

        /// Right child of this node.
        pub(crate) right: Link<T>,

        /// Parent of this node.
        ///
        /// The root node has no parent.
        pub(crate) parent: Link<T>,

        /// Red-Black color of the node.
        ///
        /// `true` means red and `false` means black.
        pub(crate) is_red: bool,

        /// Value stored in this node.
        pub(crate) value: T,
    }

    /// A link between nodes in the tree.
    ///
    /// `None` represents a missing parent or child.
    ///
    /// `Some(ptr)` contains a non-null pointer to another allocated [`Node`].
    ///
    /// Using `Option<NonNull<Node<T>>>` allows the implementation to represent
    /// nullable tree links while keeping direct pointer-based navigation between
    /// parents and children.
    pub(crate) type Link<T> = Option<NonNull<Node<T>>>;

    impl<T: Default> Node<T> {
        /// Creates the sentinel head node together with the initial tree root.
        ///
        /// The sentinel does not represent a value stored by the user. Its
        /// `value` field is initialized with [`Default::default`] and its left
        /// child becomes the first actual node in the tree.
        ///
        /// The initial root node is created as black, as required by the
        /// Red-Black Tree invariants.
        ///
        /// # Returns
        ///
        /// A link to the newly allocated sentinel node.
        ///
        /// # Implementation
        ///
        /// Both the sentinel and the root node are allocated on the heap.
        /// Ownership of these allocations is transferred to the tree and later
        /// recovered when the tree releases its nodes.
        pub(crate) fn new_fixed_head(value: T) -> Link<T> {
            let fixed_head = Box::into_non_null(Box::new(Self {
                left: None,
                right: None,
                parent: None,
                is_red: false,
                value: T::default(),
            }));
            unsafe {
                (*fixed_head.as_ptr()).left = Node::new_black(value);
            }
            Some(fixed_head)
        }
    }

    impl<T> Node<T> {
        /// Allocates a new black node.
        ///
        /// The node is created without a parent or children.
        ///
        /// # Returns
        ///
        /// A non-null link to the newly allocated node.
        ///
        /// The allocation becomes owned by the tree and must eventually be
        /// released by the tree implementation.
        pub(crate) fn new_black(value: T) -> Link<T> {
            let new = Box::into_non_null(Box::new(Self {
                left: None,
                right: None,
                parent: None,
                is_red: false,
                value,
            }));

            Some(new)
        }

        /// Allocates a new red node with the specified parent.
        ///
        /// Newly inserted Red-Black Tree nodes are initially red. The balancing
        /// algorithm may later recolor the node or rotate the surrounding
        /// subtree.
        ///
        /// The new node has no children.
        ///
        /// # Parameters
        ///
        /// - `value` — value stored in the node.
        /// - `parent` — non-null pointer to the node's parent.
        ///
        /// # Returns
        ///
        /// A non-null link to the newly allocated node.
        ///
        /// The allocation becomes owned by the tree and must eventually be
        /// released by the tree implementation.
        pub(crate) fn new_red(value: T, parent: NonNull<Node<T>>) -> Link<T> {
            let new = Box::into_non_null(Box::new(Self {
                left: None,
                right: None,
                parent: Some(parent),
                is_red: true,
                value,
            }));

            Some(new)
        }
    }
}


pub mod validation{
    use crate::node::Link;
    use crate::tree::RedBlackTree;

    impl<T: Ord + Default> RedBlackTree<T> {
        // red-red violations,
        // min black-height,
        // max black-height,
        // BST ordering,
        // parent links,
        // reachable node count
        unsafe fn validate(
            node: &Link<T>,
            expected_parent: Link<T>,
            parent_is_red: bool,
            black_height: usize,
            min: Option<&T>,
            max: Option<&T>,
        ) -> (usize, usize, usize, bool, bool, usize) {
            unsafe {
                if let Some(n) = node {
                    let value = &n.as_ref().value;

                    // 1. Check parent
                    let parent_valid = match (n.as_ref().parent, expected_parent) {
                        (None, None) => true,

                        (Some(actual), Some(expected)) => {
                            std::ptr::eq(actual.as_ptr(), expected.as_ptr())
                        }

                        _ => false,
                    };

                    // 2. Check BST ordering
                    if let Some(min) = min
                        && value <= min
                    {
                        return (0, 0, 0, false, parent_valid, 1);
                    }

                    if let Some(max) = max
                        && value >= max
                    {
                        return (0, 0, 0, false, parent_valid, 1);
                    }

                    let is_red = n.as_ref().is_red;

                    // 3. A red node cannot have a red parent.
                    let red_red = if parent_is_red && is_red { 1 } else { 0 };

                    // 4. Black height
                    let black_height = if is_red {
                        black_height
                    } else {
                        black_height + 1
                    };

                    let left = Self::validate(
                        &n.as_ref().left,
                        Some(*n),
                        is_red,
                        black_height,
                        min,
                        Some(value),
                    );

                    let right = Self::validate(
                        &n.as_ref().right,
                        Some(*n),
                        is_red,
                        black_height,
                        Some(value),
                        max,
                    );

                    (
                        red_red + left.0 + right.0,
                        std::cmp::min(left.1, right.1),
                        std::cmp::max(left.2, right.2),
                        left.3 && right.3,
                        parent_valid && left.4 && right.4,
                        1 + left.5 + right.5,
                    )
                } else {
                    (0, black_height, black_height, true, true, 0)
                }
            }
        }

        pub fn is_valid(&self) -> bool {
            unsafe {
                // tree is empty
                if self.count == 0 {
                    return match self.fixed_head {
                        None => true,

                        Some(fixed_head) => (*fixed_head.as_ptr()).left.is_none(),
                    };
                }

                // count > 0, so sentinel must exist.
                let Some(fixed_head) = self.fixed_head else {
                    return false;
                };

                // And root must exist.
                let root_link = (*fixed_head.as_ptr()).left;

                let Some(root) = root_link else {
                    return false;
                };

                // Root is always BLACK
                if root.as_ref().is_red {
                    return false;
                }

                // Root has no parent
                if root.as_ref().parent.is_some() {
                    return false;
                }

                let result = Self::validate(&root_link, None, false, 0, None, None);

                let red_red = result.0;
                let black_height_min = result.1;
                let black_height_max = result.2;
                let bst_valid = result.3;
                let parents_valid = result.4;
                let reachable_nodes = result.5;

                red_red == 0
                    && black_height_min == black_height_max
                    && bst_valid
                    && parents_valid
                    && reachable_nodes == self.count
            }
        }
    }
}


pub mod tree{
    use std::cmp::Ordering;
    use std::fmt::{Debug, Display};

    use crate::node::{Link, Node};

    use std::marker::PhantomData;
    use std::ptr::NonNull;

    use crate::iter::{IterInOrder, Range, leftmost_child_in_order, successor_of_node_in_order};

    use crate::iter::{
        IterReverseInOrder, rightmost_child_reverse_in_order, successor_of_node_reverse_in_order,
    };

    use crate::iter::{IterPreOrder, successor_of_node_pre_order};

    use crate::iter::{IterPostOrder, leaf_post_order, successor_of_node_post_order};

    use crate::iter::iter_level_order_impl;

    /// A self-balancing Red-Black Tree.
    ///
    /// `RedBlackTree` stores unique values in sorted order.
    ///
    /// Insert, lookup and removal operations have logarithmic
    /// expected tree height due to Red-Black Tree balancing.
    ///
    /// # Examples
    ///
    /// ```
    /// use rbtree_extended::RedBlackTree;
    ///
    /// let mut tree = RedBlackTree::new();
    ///
    /// tree.insert(3);
    /// tree.insert(1);
    /// tree.insert(2);
    ///
    /// assert_eq!(tree.len(), 3);
    /// assert!(tree.contains(&2));
    /// ```
    pub struct RedBlackTree<T: Ord + Default> {
        pub(crate) fixed_head: Link<T>,
        pub(crate) count: usize,
        _marker: PhantomData<T>,
    }

    enum OperationPut {
        Left,
        Right,
        FlipColors,
        Nothing,
    }

    enum OperationRemove {
        RedLeaf,
        BlackLeaf,
        NodeWithChildren,
        BlackNodeWithRedLeaf,
    }

    enum OperationRemoveBlackLeaf {
        LeftRedABlackBRedCleaf,                      // 2.1.1.1
        RightRedABlackBRedCleaf,                     // 2.1.1.2
        LeftRedABlackBleaf,                          // 2.1.2.1
        RightRedABlackBleaf,                         // 2.1.2.2
        BlackARedBWithBlackChildrenLeaf,             // 2.2.4
        BlackARedBWithBlackChildrenRightHaveRedLeaf, // 2.2.1
        BlackALeftBlackBRedDleaf,                    // 2.3.1.1
        BlackARightBlackBRedDleaf,                   // 2.3.1.2
        BlackALeftBlackBleaf,                        // 2.3.2.1
        BlackARightBlackBleaf,                       // 2.3.2.2
        Root,
        Unimplemented,
    }

    impl<T: Ord + Default + Display> RedBlackTree<T> {
        /// Exports the tree in Graphviz DOT format.
        ///
        /// The returned string can be rendered using Graphviz-compatible tools.
        ///
        /// An empty tree produces a valid empty DOT graph.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.insert(10);
        /// tree.insert(5);
        /// tree.insert(20);
        ///
        /// let dot = tree.to_dot();
        ///
        /// println!("{dot}");
        /// ```
        pub fn to_dot(&self) -> String {
            unsafe {
                let Some(fixed_head) = self.fixed_head else {
                    return "digraph Tree {}".into();
                };

                let Some(root) = (*fixed_head.as_ptr()).left else {
                    return "digraph Tree {}".into();
                };

                format!(
                    "\ndigraph Tree {{\n\tratio = fill;\n\tnode [style=filled fontcolor=\"white\"];\n{}}}",
                    helper_display_tree(root)
                )
            }
        }
    }

    impl<T: Ord + Default> RedBlackTree<T> {
        /// Creates an empty Red-Black Tree.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let tree = RedBlackTree::<i32>::new();
        ///
        /// assert!(tree.is_empty());
        /// ```
        pub fn new() -> Self {
            Self {
                fixed_head: None,
                count: 0,
                _marker: PhantomData,
            }
        }

        /// Returns the number of values stored in the tree.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.insert(10);
        /// tree.insert(20);
        ///
        /// assert_eq!(tree.len(), 2);
        /// ```
        pub fn len(&self) -> usize {
            self.count
        }

        /// Returns `true` if the tree contains no values.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::<i32>::new();
        /// assert!(tree.is_empty());
        ///
        /// tree.insert(10);
        /// assert!(!tree.is_empty());
        /// ```
        pub fn is_empty(&self) -> bool {
            self.count == 0
        }

        /// Removes all values from the tree.
        ///
        /// After calling `clear`, the tree is empty and can be reused.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([1, 2, 3]);
        ///
        /// tree.clear();
        ///
        /// assert!(tree.is_empty());
        /// assert_eq!(tree.len(), 0);
        /// ```
        pub fn clear(&mut self) {
            unsafe {
                if let Some(fixed_head) = self.fixed_head {
                    let root = (*fixed_head.as_ptr()).left;

                    (*fixed_head.as_ptr()).left = None;

                    self.remove_tree(root);
                }

                debug_assert_eq!(self.count, 0);
            }
        }

        /// Returns the smallest value in the tree.
        ///
        /// Returns `None` if the tree is empty.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([8, 3, 10, 1]);
        ///
        /// assert_eq!(tree.first(), Some(&1));
        /// ```
        pub fn first(&self) -> Option<&T> {
            self.minimum()
        }

        /// Returns the largest value in the tree.
        ///
        /// Returns `None` if the tree is empty.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([8, 3, 10, 14]);
        ///
        /// assert_eq!(tree.last(), Some(&14));
        /// ```
        pub fn last(&self) -> Option<&T> {
            self.maximum()
        }

        fn minimum(&self) -> Option<&T> {
            unsafe {
                let root = self.get_root()?;
                let node = self.find_min(root);
                Some(&node.as_ref().value)
            }
        }

        fn maximum(&self) -> Option<&T> {
            unsafe {
                let root = self.get_root()?;
                let node = self.find_max(root);

                Some(&node.as_ref().value)
            }
        }

        /// Returns the height of the tree.
        ///
        /// An empty tree has height `0`.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// assert_eq!(tree.height(), 0);
        ///
        /// tree.insert(10);
        /// assert_eq!(tree.height(), 1);
        /// ```
        pub fn height(&self) -> usize {
            unsafe fn height_from<T>(node: Link<T>) -> usize {
                unsafe {
                    match node {
                        None => 0,

                        Some(node) => {
                            let left_height = height_from(node.as_ref().left);
                            let right_height = height_from(node.as_ref().right);

                            1 + left_height.max(right_height)
                        }
                    }
                }
            }

            unsafe { height_from(self.get_root()) }
        }

        /// Returns `true` if the tree contains `value`.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([1, 3, 5]);
        ///
        /// assert!(tree.contains(&3));
        /// assert!(!tree.contains(&4));
        /// ```
        pub fn contains(&self, value: &T) -> bool {
            !find_node(self.get_root(), value).is_none()
        }

        /// Inserts a value into the tree.
        ///
        /// Returns `true` if the value was inserted.
        ///
        /// Returns `false` if the value already exists.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        ///
        /// assert!(tree.insert(10));
        /// assert!(!tree.insert(10));
        /// ```
        pub fn insert(&mut self, value: T) -> bool {
            unsafe {
                if let Some(fixed_head) = self.fixed_head {
                    if (*fixed_head.as_ptr()).left.is_none() {
                        (*fixed_head.as_ptr()).left = Node::new_black(value);
                        self.count += 1;
                        return true;
                    }

                    let parent = self.find_put_parent_candidate(self.get_root(), &value);

                    if let Some(parent) = parent {
                        if self.attach_node(parent, value) {
                            self.put_balancing(parent);
                        } else {
                            return false;
                        }
                    } else {
                        return false;
                    }
                } else {
                    self.fixed_head = Node::new_fixed_head(value);
                }

                self.count += 1;
                true
            }
        }

        /// Removes a value from the tree.
        ///
        /// Returns `true` if the value existed and was removed.
        ///
        /// Use [`RedBlackTree::take`] when ownership of the removed value is needed.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.insert(10);
        ///
        /// assert!(tree.remove(&10));
        /// assert!(!tree.contains(&10));
        /// assert!(!tree.remove(&10));
        /// ```
        pub fn remove(&mut self, value: &T) -> bool {
            self.take(value).is_some()
        }

        /// Inserts `value` into the tree, replacing an existing equal value.
        ///
        /// If the tree already contains a value that compares equal to `value`,
        /// the existing value is replaced and returned.
        ///
        /// If no equal value exists, `value` is inserted and `None` is returned.
        ///
        /// This is especially useful for custom types whose [`Ord`] implementation
        /// compares only a key field.
        ///
        /// # Examples
        ///
        /// ```
        /// use std::cmp::Ordering;
        /// use rbtree_extended::RedBlackTree;
        ///
        /// #[derive(Debug, Default)]
        /// struct User {
        ///     id: u32,
        ///     name: String,
        /// }
        ///
        /// impl PartialEq for User {
        ///     fn eq(&self, other: &Self) -> bool {
        ///         self.id == other.id
        ///     }
        /// }
        ///
        /// impl Eq for User {}
        ///
        /// impl PartialOrd for User {
        ///     fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        ///         Some(self.cmp(other))
        ///     }
        /// }
        ///
        /// impl Ord for User {
        ///     fn cmp(&self, other: &Self) -> Ordering {
        ///         self.id.cmp(&other.id)
        ///     }
        /// }
        ///
        /// let mut users = RedBlackTree::new();
        ///
        /// users.insert(User {
        ///     id: 1,
        ///     name: "Alice".into(),
        /// });
        ///
        /// let old = users.replace(User {
        ///     id: 1,
        ///     name: "Bob".into(),
        /// });
        ///
        /// assert_eq!(old.unwrap().name, "Alice");
        /// assert_eq!(users.first().unwrap().name, "Bob");
        /// ```
        pub fn replace(&mut self, value: T) -> Option<T> {
            unsafe {
                if let Some(mut node) = find_node(self.get_root(), &value) {
                    return Some(std::mem::replace(&mut node.as_mut().value, value));
                }
            }

            self.insert(value);

            None
        }

        unsafe fn take_node(&mut self, mut node: NonNull<Node<T>>) -> Option<T> {
            unsafe {
                // Save the original value before the internal removal algorithm
                // starts swapping values between nodes.
                let removed_value = std::mem::take(&mut node.as_mut().value);

                if !self.remove_node(node) {
                    return None;
                }

                self.count -= 1;

                Some(removed_value)
            }
        }

        /// Removes and returns the value equal to `value`.
        ///
        /// Returns `None` if the value is not present in the tree.
        ///
        /// Unlike [`RedBlackTree::remove`], this method gives ownership of the
        /// removed value back to the caller.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([10, 5, 20]);
        ///
        /// assert_eq!(tree.take(&10), Some(10));
        /// assert!(!tree.contains(&10));
        /// assert_eq!(tree.take(&100), None);
        /// ```
        pub fn take(&mut self, value: &T) -> Option<T> {
            if self.is_empty() {
                return None;
            }

            unsafe {
                let node = find_node(self.get_root(), value)?;
                self.take_node(node)
            }
        }

        /// Retains only the values specified by the predicate.
        ///
        /// In other words, removes every value for which `f(&value)` returns `false`.
        ///
        /// The predicate receives a shared reference to each stored value.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([1, 2, 3, 4, 5, 6]);
        ///
        /// tree.retain(|value| value % 2 == 0);
        ///
        /// assert_eq!(
        ///     tree.iter().copied().collect::<Vec<_>>(),
        ///     vec![2, 4, 6]
        /// );
        /// ```
        ///
        /// Retaining no values empties the tree:
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([1, 2, 3]);
        ///
        /// tree.retain(|_| false);
        ///
        /// assert!(tree.is_empty());
        /// ```
        pub fn retain<F>(&mut self, mut f: F)
        where
            F: FnMut(&T) -> bool,
        {
            let mut retained = Self::new();

            while let Some(value) = self.pop_first() {
                if f(&value) {
                    retained.insert(value);
                }
            }

            *self = retained;
        }

        /// Removes and returns the smallest value in the tree.
        ///
        /// Returns `None` if the tree is empty.
        ///
        /// This operation is useful when values need to be processed in
        /// ascending order.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([8, 3, 10, 1, 6]);
        ///
        /// assert_eq!(tree.pop_first(), Some(1));
        /// assert_eq!(tree.pop_first(), Some(3));
        /// assert_eq!(tree.len(), 3);
        /// ```
        pub fn pop_first(&mut self) -> Option<T> {
            unsafe {
                let root = self.get_root()?;
                let node = self.find_min(root);

                self.take_node(node)
            }
        }

        /// Removes and returns the largest value in the tree.
        ///
        /// Returns `None` if the tree is empty.
        ///
        /// This operation can be used to implement a priority queue where the
        /// greatest value represents the highest priority.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([8, 3, 10, 1, 6]);
        ///
        /// assert_eq!(tree.pop_last(), Some(10));
        /// assert_eq!(tree.pop_last(), Some(8));
        /// assert_eq!(tree.len(), 3);
        /// ```
        pub fn pop_last(&mut self) -> Option<T> {
            unsafe {
                let root = self.get_root()?;
                let node = self.find_max(root);

                self.take_node(node)
            }
        }

        /// Returns a reference to the stored value equal to `value`.
        ///
        /// Returns `None` if no matching value exists.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([1, 3, 5]);
        ///
        /// assert_eq!(tree.get(&3), Some(&3));
        /// assert_eq!(tree.get(&4), None);
        /// ```
        pub fn get(&self, value: &T) -> Option<&T> {
            unsafe {
                let node = find_node(self.get_root(), value)?;
                Some(&node.as_ref().value)
            }
        }

        /// Returns the next greater value in sorted order.
        ///
        /// Returns `None` if `value` is not present or if it is the largest value.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([1, 3, 5, 7]);
        ///
        /// assert_eq!(tree.successor(&3), Some(&5));
        /// assert_eq!(tree.successor(&7), None);
        /// ```
        pub fn successor(&self, value: &T) -> Option<&T> {
            unsafe {
                let node = find_node(self.get_root(), value)?;

                // Case 1:
                // there is a right subtree - successor = minimum element on the right
                if let Some(right) = node.as_ref().right {
                    let successor = self.find_min(right);
                    return Some(&successor.as_ref().value);
                }

                // Case 2:
                // there is no right subtree
                // Move up while the current node is a right child
                let mut current = node;
                let mut parent = current.as_ref().parent;

                while let Some(p) = parent {
                    if let Some(left) = p.as_ref().left
                        && std::ptr::eq(left.as_ptr(), current.as_ptr())
                    {
                        return Some(&p.as_ref().value);
                    }

                    current = p;
                    parent = p.as_ref().parent;
                }

                None
            }
        }

        /// Returns the previous smaller value in sorted order.
        ///
        /// Returns `None` if `value` is not present or if it is the smallest value.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([1, 3, 5, 7]);
        ///
        /// assert_eq!(tree.predecessor(&5), Some(&3));
        /// assert_eq!(tree.predecessor(&1), None);
        /// ```
        pub fn predecessor(&self, value: &T) -> Option<&T> {
            unsafe {
                let node = find_node(self.get_root(), value)?;

                // Case 1:
                // there is a left subtree - predecessor = maximum element on the left
                if let Some(left) = node.as_ref().left {
                    let predecessor = self.find_max(left);
                    return Some(&predecessor.as_ref().value);
                }

                // Case 2:
                // there is no left subtree
                // Move up while the current node is a left child
                let mut current = node;
                let mut parent = current.as_ref().parent;

                while let Some(p) = parent {
                    if let Some(right) = p.as_ref().right
                        && std::ptr::eq(right.as_ptr(), current.as_ptr())
                    {
                        return Some(&p.as_ref().value);
                    }

                    current = p;
                    parent = p.as_ref().parent;
                }

                None
            }
        }

        /// Returns the first value greater than or equal to `value`.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([1, 3, 6, 8]);
        ///
        /// assert_eq!(tree.lower_bound(&5), Some(&6));
        /// assert_eq!(tree.lower_bound(&6), Some(&6));
        /// ```
        pub fn lower_bound(&self, value: &T) -> Option<&T> {
            unsafe {
                let mut current = self.get_root();
                let mut candidate: Link<T> = None;

                while let Some(node) = current {
                    match node.as_ref().value.cmp(value) {
                        Ordering::Less => {
                            current = node.as_ref().right;
                        }

                        Ordering::Equal => {
                            return Some(&node.as_ref().value);
                        }

                        Ordering::Greater => {
                            candidate = Some(node);
                            current = node.as_ref().left;
                        }
                    }
                }

                candidate.map(|node| &node.as_ref().value)
            }
        }

        /// Returns the first value strictly greater than `value`.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([1, 3, 6, 8]);
        ///
        /// assert_eq!(tree.upper_bound(&6), Some(&8));
        /// assert_eq!(tree.upper_bound(&8), None);
        /// ```
        pub fn upper_bound(&self, value: &T) -> Option<&T> {
            unsafe {
                let mut current = self.get_root();
                let mut candidate: Link<T> = None;

                while let Some(node) = current {
                    match node.as_ref().value.cmp(value) {
                        Ordering::Less | Ordering::Equal => {
                            current = node.as_ref().right;
                        }
                        Ordering::Greater => {
                            candidate = Some(node);
                            current = node.as_ref().left;
                        }
                    }
                }

                candidate.map(|node| &node.as_ref().value)
            }
        }

        /// Returns an iterator over values in the inclusive range `[min, max]`.
        ///
        /// Values are yielded in ascending order.
        ///
        /// The iterator is lazy: values are produced only as they are requested,
        /// rather than being collected into an intermediate `Vec`.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([1, 3, 5, 7, 9, 11]);
        ///
        /// let values: Vec<_> = tree
        ///     .range(&3, &9)
        ///     .copied()
        ///     .collect();
        ///
        /// assert_eq!(values, vec![3, 5, 7, 9]);
        /// ```
        pub fn range(&self, min: &T, max: &T) -> Range<'_, T> {
            Range::new(self.get_root(), min, max)
        }

        /// Returns the next value in an in-order (`LNR`) traversal.
        ///
        /// For a binary search tree, in-order traversal visits values in ascending order.
        ///
        /// Returns `None` if `value` is not present or has no successor in this traversal.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([4, 2, 6, 1, 3, 5, 7]);
        ///
        /// assert_eq!(tree.successor_dfs_in_order(4), Some(&5));
        /// ```
        pub fn successor_dfs_in_order(&self, value: T) -> Option<&T> {
            unsafe {
                let node = find_node(self.get_root(), &value);
                if let Some(n) = node
                    && let Some(nodesucc) = successor_of_node_in_order(n)
                {
                    return Some(&nodesucc.as_ref().value);
                }
                None
            }
        }

        /// Returns the next value in reverse in-order (`RNL`) traversal.
        ///
        /// For a binary search tree, reverse in-order traversal visits values in
        /// descending order.
        ///
        /// Returns `None` if `value` is not present or has no successor in this traversal.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([4, 2, 6, 1, 3, 5, 7]);
        ///
        /// assert_eq!(tree.successor_dfs_reverse_in_order(6), Some(&5));
        /// ```
        pub fn successor_dfs_reverse_in_order(&self, value: T) -> Option<&T> {
            unsafe {
                if let Some(node) = find_node(self.get_root(), &value)
                    && let Some(next) = successor_of_node_reverse_in_order(node)
                {
                    return Some(&next.as_ref().value);
                }
                None
            }
        }

        /// Returns the next value in post-order (`LRN`) traversal.
        ///
        /// Post-order visits the left subtree, then the right subtree,
        /// and finally the current node.
        ///
        /// Returns `None` if `value` is not present or has no successor in this traversal.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([4, 2, 6, 1, 3, 5, 7]);
        ///
        /// // Post-order: 1, 3, 2, 5, 7, 6, 4
        /// assert_eq!(tree.successor_dfs_post_order(3), Some(&2));
        /// assert_eq!(tree.successor_dfs_post_order(2), Some(&5));
        /// assert_eq!(tree.successor_dfs_post_order(4), None);
        /// ```
        pub fn successor_dfs_post_order(&self, value: T) -> Option<&T> {
            unsafe {
                if let Some(n) = find_node(self.get_root(), &value)
                    && let Some(nodesucc) = successor_of_node_post_order(n)
                {
                    return Some(&nodesucc.as_ref().value);
                }
                None
            }
        }

        /// Returns the next value in pre-order (`NLR`) traversal.
        ///
        /// Pre-order visits the current node first, followed by the left and right
        /// subtrees.
        ///
        /// Returns `None` if `value` is not present or has no successor in this traversal.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([4, 2, 6, 1, 3, 5, 7]);
        ///
        /// let first = *tree.iter_preorder().next().unwrap();
        /// assert_eq!(tree.successor_dfs_pre_order(first), tree.iter_preorder().nth(1));
        /// ```
        pub fn successor_dfs_pre_order(&self, value: T) -> Option<&T> {
            unsafe {
                if let Some(n) = find_node(self.get_root(), &value)
                    && let Some(nodesucc) = successor_of_node_pre_order(n)
                {
                    return Some(&nodesucc.as_ref().value);
                }
                None
            }
        }

        fn get_root(&self) -> Link<T> {
            if let Some(fixed_head) = self.fixed_head {
                unsafe { (*fixed_head.as_ptr()).left }
            } else {
                None
            }
        }

        unsafe fn operation_remove(&self, node_x: &NonNull<Node<T>>) -> OperationRemove {
            unsafe {
                if node_x.as_ref().is_red
                    && node_x.as_ref().left.is_none()
                    && node_x.as_ref().right.is_none()
                {
                    return OperationRemove::RedLeaf;
                }
                if node_x.as_ref().is_red
                    && node_x.as_ref().left.is_some()
                    && node_x.as_ref().right.is_some()
                {
                    return OperationRemove::NodeWithChildren;
                }
                if !node_x.as_ref().is_red {
                    if node_x.as_ref().left.is_some() && node_x.as_ref().right.is_some() {
                        return OperationRemove::NodeWithChildren;
                    } else if node_x.as_ref().left.is_some() && node_x.as_ref().right.is_none() {
                        if let Some(left) = node_x.as_ref().left
                            && left.as_ref().is_red
                            && left.as_ref().left.is_none()
                            && left.as_ref().right.is_none()
                        {
                            return OperationRemove::BlackNodeWithRedLeaf;
                        }
                    } else if node_x.as_ref().left.is_none() && node_x.as_ref().right.is_none() {
                        return OperationRemove::BlackLeaf;
                    }
                }
                panic!();
            }
        }

        unsafe fn operation_remove_black_leaf(
            &self,
            node_x: &NonNull<Node<T>>,
        ) -> OperationRemoveBlackLeaf {
            unsafe {
                if let Some(node_a) = node_x.as_ref().parent {
                    if node_a.as_ref().is_red {
                        if let Some(node_b) = node_a.as_ref().left
                            && !std::ptr::eq(node_b.as_ptr(), node_x.as_ptr())
                            && !node_b.as_ref().is_red
                        {
                            if let Some(node_c) = node_b.as_ref().left
                                && node_c.as_ref().is_red
                            {
                                return OperationRemoveBlackLeaf::LeftRedABlackBRedCleaf;
                                // 2.1.1.1
                            }

                            // sibling B is black and its left child is either absent or also black
                            return OperationRemoveBlackLeaf::LeftRedABlackBleaf;
                            // 2.1.2.1
                        }

                        if let Some(node_b) = node_a.as_ref().right
                            && !std::ptr::eq(node_b.as_ptr(), node_x.as_ptr())
                            && !node_b.as_ref().is_red
                        {
                            if let Some(node_c) = node_b.as_ref().left
                                && node_c.as_ref().is_red
                            {
                                return OperationRemoveBlackLeaf::RightRedABlackBRedCleaf;
                                // 2.1.1.2
                            }

                            // sibling B is black and its left child is either absent or also black
                            return OperationRemoveBlackLeaf::RightRedABlackBleaf;
                            // 2.1.2.2
                        }
                    } else {
                        if let Some(node_b) = node_a.as_ref().left
                            && !std::ptr::eq(node_b.as_ptr(), node_x.as_ptr())
                        {
                            if node_b.as_ref().is_red && node_b.as_ref().right.is_some() {
                                let node_c = node_b.as_ref().right.unwrap();
                                if !node_c.as_ref().is_red {
                                    if node_c.as_ref().left.is_some()
                                        && let Some(node_d) = node_c.as_ref().left
                                        && node_d.as_ref().is_red
                                    {
                                        return OperationRemoveBlackLeaf::BlackARedBWithBlackChildrenRightHaveRedLeaf;
                                        // 2.2.1
                                    }
                                    return OperationRemoveBlackLeaf::BlackARedBWithBlackChildrenLeaf;
                                    // 2.2.2
                                }
                            }
                            if !node_b.as_ref().is_red
                                && node_b.as_ref().left.is_some()
                                && let Some(node_d) = node_b.as_ref().left
                                && node_d.as_ref().is_red
                            {
                                return OperationRemoveBlackLeaf::BlackALeftBlackBRedDleaf;
                                // 2.3.1.1
                            }
                            if !node_b.as_ref().is_red {
                                return OperationRemoveBlackLeaf::BlackALeftBlackBleaf;
                                // 2.3.2.1
                            }
                        }
                        if let Some(node_b) = node_a.as_ref().right
                            && !std::ptr::eq(node_b.as_ptr(), node_x.as_ptr())
                        {
                            if !node_b.as_ref().is_red
                                && node_b.as_ref().left.is_some()
                                && let Some(node_d) = node_b.as_ref().left
                                && node_d.as_ref().is_red
                            {
                                return OperationRemoveBlackLeaf::BlackARightBlackBRedDleaf;
                                // 2.3.1.2
                            }
                            if !node_b.as_ref().is_red {
                                return OperationRemoveBlackLeaf::BlackARightBlackBleaf;
                                // 2.3.2.2
                            }
                        }
                    }
                } else {
                    return OperationRemoveBlackLeaf::Root;
                }
                OperationRemoveBlackLeaf::Unimplemented
            }
        }

        unsafe fn remove_black_leaf(&mut self, node_x: NonNull<Node<T>>) -> bool {
            unsafe {
                let mut next = node_x;
                let mut removed = false;
                loop {
                    match self.operation_remove_black_leaf(&next) {
                        OperationRemoveBlackLeaf::LeftRedABlackBRedCleaf => {
                            self.remove_black_leaf_2_1_1_1_balancing(&next);
                            if !removed {
                                removed = self.remove_leaf(node_x);
                            }
                            break;
                        }
                        OperationRemoveBlackLeaf::RightRedABlackBRedCleaf => {
                            self.remove_black_leaf_2_1_1_2_balancing(&next);
                            if !removed {
                                removed = self.remove_leaf(node_x);
                            }
                            break;
                        }
                        OperationRemoveBlackLeaf::LeftRedABlackBleaf => {
                            self.remove_black_leaf_2_1_2_1_balancing(&next);
                            if !removed {
                                removed = self.remove_leaf(node_x);
                            }
                            break;
                        }
                        OperationRemoveBlackLeaf::RightRedABlackBleaf => {
                            self.remove_black_leaf_2_1_2_2_balancing(&next);
                            if !removed {
                                removed = self.remove_leaf(node_x);
                            }
                            break;
                        }
                        OperationRemoveBlackLeaf::BlackARedBWithBlackChildrenRightHaveRedLeaf => {
                            self.remove_black_leaf_2_2_1_balancing(&next);
                            if !removed {
                                removed = self.remove_leaf(node_x);
                            }
                            break;
                        }
                        OperationRemoveBlackLeaf::BlackARedBWithBlackChildrenLeaf => {
                            self.remove_black_leaf_2_2_2_balancing(&next);
                            if !removed {
                                removed = self.remove_leaf(node_x);
                            }
                            break;
                        }
                        OperationRemoveBlackLeaf::BlackALeftBlackBRedDleaf => {
                            self.remove_black_leaf_2_3_1_1_balancing(&next);
                            if !removed {
                                removed = self.remove_leaf(node_x);
                            }
                            break;
                        }
                        OperationRemoveBlackLeaf::BlackARightBlackBRedDleaf => {
                            self.remove_black_leaf_2_3_1_2_balancing(&next);
                            if !removed {
                                removed = self.remove_leaf(node_x);
                            }
                            break;
                        }
                        OperationRemoveBlackLeaf::BlackALeftBlackBleaf => {
                            next = self.remove_black_leaf_2_3_2_1_balancing(&next);
                            if !removed {
                                removed = self.remove_leaf(node_x);
                            }
                        }
                        OperationRemoveBlackLeaf::BlackARightBlackBleaf => {
                            next = self.remove_black_leaf_2_3_2_2_balancing(&next);
                            if !removed {
                                removed = self.remove_leaf(node_x);
                            }
                        }
                        OperationRemoveBlackLeaf::Root => {
                            if !removed {
                                // We get here when the node_x being deleted is root
                                if let Some(fixed_head) = self.fixed_head {
                                    (*fixed_head.as_ptr()).left = None;
                                }
                                let _ = Box::from_raw(node_x.as_ptr());
                                removed = true;
                            }
                            break;
                        }
                        OperationRemoveBlackLeaf::Unimplemented => {
                            panic!("unimplemented black leaf removal case");
                        }
                    }
                }
                removed
            }
        }

        /// 2.1.1.1 remove black X
        ///
        /// ```text
        ///             P            P
        ///            //           //
        ///            A            B
        ///           / \          / \
        ///          B   X   =>   C   A
        ///         //\              /
        ///        C   D            D
        /// ```
        unsafe fn remove_black_leaf_2_1_1_1_balancing(&mut self, node_x: &NonNull<Node<T>>) {
            unsafe {
                let node_a = (*node_x.as_ptr()).parent.unwrap();
                let node_b = (*node_a.as_ptr()).left.unwrap();
                let node_d = (*node_b.as_ptr()).right;
                (*node_b.as_ptr()).parent = (*node_a.as_ptr()).parent;
                if let Some(ref mut parent) = (*node_b.as_ptr()).parent {
                    (*parent.as_ptr()).left = Some(node_b);
                }
                (*node_a.as_ptr()).left = node_d;
                if let Some(n_d) = node_d {
                    (*n_d.as_ptr()).parent = Some(node_a);
                }
                (*node_a.as_ptr()).is_red = false;
                (*node_b.as_ptr()).right = Some(node_a);
                (*node_a.as_ptr()).parent = Some(node_b);
                (*node_b.as_ptr()).is_red = true;
                if let Some(node_c) = (*node_b.as_ptr()).left {
                    (*node_c.as_ptr()).is_red = false;
                }
            }
        }

        /// 2.1.1.2 remove black X
        ///
        /// ```text
        ///             P              P
        ///            //             //
        ///           A               C
        ///          / \            /   \
        ///         X   B   =>     A     B
        ///            //           \   /
        ///            C             E D
        ///           / \
        ///          E   D
        /// ```
        unsafe fn remove_black_leaf_2_1_1_2_balancing(&mut self, node_x: &NonNull<Node<T>>) {
            unsafe {
                let node_a = (*node_x.as_ptr()).parent.unwrap();
                (*node_a.as_ptr()).is_red = false;
                let parent: NonNull<Node<T>> = (*node_a.as_ptr()).parent.unwrap();
                let node_b = (*node_a.as_ptr()).right.unwrap();
                let node_c = (*node_b.as_ptr()).left.unwrap();
                let node_e = (*node_c.as_ptr()).left;
                let node_d = (*node_c.as_ptr()).right;
                (*parent.as_ptr()).left = Some(node_c);
                (*node_c.as_ptr()).parent = Some(parent);
                (*node_b.as_ptr()).left = node_d;
                if let Some(n_d) = node_d {
                    (*n_d.as_ptr()).parent = Some(node_b);
                }
                (*node_c.as_ptr()).right = Some(node_b);
                (*node_b.as_ptr()).parent = Some(node_c);
                (*node_c.as_ptr()).left = Some(node_a);
                (*node_a.as_ptr()).parent = Some(node_c);
                (*node_a.as_ptr()).right = node_e;
                if let Some(n_e) = node_e {
                    (*n_e.as_ptr()).parent = Some(node_a);
                }
            }
        }

        /// 2.1.2.1 remove black X
        ///
        /// ```text
        ///              P            P
        ///             //           /
        ///            A            A
        ///           / \          //
        ///          B   X   =>   B
        ///
        /// ```
        unsafe fn remove_black_leaf_2_1_2_1_balancing(&mut self, node_x: &NonNull<Node<T>>) {
            unsafe {
                let node_a = (*node_x.as_ptr()).parent.unwrap();
                (*node_a.as_ptr()).is_red = false;
                if let Some(node_b) = (*node_a.as_ptr()).left {
                    (*node_b.as_ptr()).is_red = true;
                }
            }
        }

        /// 2.1.2.2 remove black X
        ///
        /// ```text
        ///             P            P
        ///            //           /
        ///            A     =>     B
        ///           / \          //\
        ///          X   B        A   D
        ///             / \        \
        ///            C   D        C
        /// ```
        unsafe fn remove_black_leaf_2_1_2_2_balancing(&mut self, node_x: &NonNull<Node<T>>) {
            unsafe {
                let node_a = (*node_x.as_ptr()).parent.unwrap();
                let node_b = (*node_a.as_ptr()).right.unwrap();
                let node_c = (*node_b.as_ptr()).left;
                let node_d = (*node_b.as_ptr()).right;
                let parent = (*node_a.as_ptr()).parent.unwrap();
                if let Some(left) = (*parent.as_ptr()).left {
                    if std::ptr::eq(node_a.as_ptr(), left.as_ptr()) {
                        (*parent.as_ptr()).left = Some(node_b);
                    } else {
                        (*parent.as_ptr()).right = Some(node_b);
                    }
                } else {
                    (*parent.as_ptr()).right = Some(node_b);
                }
                (*node_b.as_ptr()).parent = Some(parent);
                (*node_b.as_ptr()).left = Some(node_a);
                (*node_b.as_ptr()).right = node_d;
                if let Some(n_d) = node_d {
                    (*n_d.as_ptr()).parent = Some(node_b);
                }
                (*node_a.as_ptr()).parent = Some(node_b);
                (*node_a.as_ptr()).right = node_c;
                if let Some(n_c) = node_c {
                    (*n_c.as_ptr()).parent = Some(node_a);
                }
            }
        }

        /// 2.2.1 remove black X
        ///
        /// ```text
        ///            A               C
        ///          // \            //  \
        ///         B    X    =>    B     A
        ///          \               \   /
        ///           C               D E
        ///           //\
        ///          D   E
        /// ```
        unsafe fn remove_black_leaf_2_2_1_balancing(&mut self, node_x: &NonNull<Node<T>>) {
            unsafe {
                let n_a = node_x.as_ref().parent.unwrap();
                if n_a.as_ref().parent.is_some() {
                    let parent = (*n_a.as_ptr()).parent.unwrap();
                    let mut node_a_from_left = false;
                    if let Some(ref mut node_a) = (*parent.as_ptr()).left
                        && std::ptr::eq(node_a.as_ptr(), n_a.as_ptr())
                    {
                        node_a_from_left = true;
                    }
                    let node_a = if node_a_from_left {
                        (*parent.as_ptr()).left.unwrap()
                    } else {
                        (*parent.as_ptr()).right.unwrap()
                    };
                    let node_b = (*node_a.as_ptr()).left.unwrap();
                    let node_c = (*node_b.as_ptr()).right.unwrap();
                    let node_e = (*node_c.as_ptr()).right;
                    let node_d = (*node_c.as_ptr()).left.unwrap();
                    (*node_b.as_ptr()).right = Some(node_d);
                    (*node_b.as_ptr()).parent = Some(node_c);
                    (*node_d.as_ptr()).parent = Some(node_b);
                    (*node_a.as_ptr()).parent = Some(node_c);
                    (*node_a.as_ptr()).left = node_e;
                    if let Some(n_e) = node_e {
                        (*n_e.as_ptr()).parent = Some(node_a);
                    }
                    (*node_d.as_ptr()).is_red = false;
                    (*node_c.as_ptr()).left = Some(node_b);
                    (*node_c.as_ptr()).right = Some(node_a);
                    (*node_c.as_ptr()).parent = Some(parent);
                    if node_a_from_left {
                        (*parent.as_ptr()).left = Some(node_c);
                    } else {
                        (*parent.as_ptr()).right = Some(node_c);
                    }
                } else {
                    // node_a is root
                    if let Some(fixed_head) = self.fixed_head {
                        let node_a = (*fixed_head.as_ptr()).left.unwrap();
                        let node_b = (*node_a.as_ptr()).left.unwrap();
                        let node_c = (*node_b.as_ptr()).right.unwrap();
                        let node_e = (*node_c.as_ptr()).right;
                        let node_d = (*node_c.as_ptr()).left.unwrap();
                        (*node_b.as_ptr()).right = Some(node_d);
                        (*node_b.as_ptr()).parent = Some(node_c);
                        (*node_d.as_ptr()).parent = Some(node_b);
                        (*node_a.as_ptr()).parent = Some(node_c);
                        (*node_a.as_ptr()).left = node_e;
                        if let Some(n_e) = node_e {
                            (*n_e.as_ptr()).parent = Some(node_a);
                        }
                        (*node_d.as_ptr()).is_red = false;
                        (*node_c.as_ptr()).left = Some(node_b);
                        (*node_c.as_ptr()).right = Some(node_a);
                        (*node_c.as_ptr()).parent = None;
                        (*fixed_head.as_ptr()).left = Some(node_c);
                    }
                }
            }
        }

        /// 2.2.2 remove black X
        ///
        /// ```text
        ///    A            B
        ///  // \            \
        ///  B    X   =>       A
        ///  \               //
        ///   C             C
        /// ```
        unsafe fn remove_black_leaf_2_2_2_balancing(&mut self, node_x: &NonNull<Node<T>>) {
            unsafe {
                let n_a = node_x.as_ref().parent.unwrap();
                if n_a.as_ref().parent.is_some() {
                    let parent = (*n_a.as_ptr()).parent.unwrap();
                    let mut node_a_from_left = false;
                    if let Some(ref mut node_a) = (*parent.as_ptr()).left
                        && std::ptr::eq(node_a.as_ptr(), n_a.as_ptr())
                    {
                        node_a_from_left = true;
                    }
                    let node_a = if node_a_from_left {
                        (*parent.as_ptr()).left.unwrap()
                    } else {
                        (*parent.as_ptr()).right.unwrap()
                    };
                    let node_b = (*node_a.as_ptr()).left.unwrap();
                    (*node_b.as_ptr()).is_red = false;
                    (*node_b.as_ptr()).parent = Some(parent);
                    let node_c = (*node_b.as_ptr()).right.unwrap();
                    (*node_c.as_ptr()).is_red = true;
                    (*node_b.as_ptr()).right = Some(node_a);
                    (*node_a.as_ptr()).left = Some(node_c);
                    (*node_c.as_ptr()).parent = Some(node_a);
                    (*node_a.as_ptr()).parent = Some(node_b);
                    if node_a_from_left {
                        (*parent.as_ptr()).left = Some(node_b);
                    } else {
                        (*parent.as_ptr()).right = Some(node_b);
                    }
                } else {
                    // node_a is root
                    if let Some(fixed_head) = self.fixed_head {
                        let node_a = (*fixed_head.as_ptr()).left.unwrap();
                        let node_b = (*node_a.as_ptr()).left.unwrap();
                        (*node_b.as_ptr()).is_red = false;
                        (*node_b.as_ptr()).parent = None;
                        let node_c = (*node_b.as_ptr()).right.unwrap();
                        (*node_c.as_ptr()).is_red = true;
                        (*node_b.as_ptr()).right = Some(node_a);
                        (*node_a.as_ptr()).left = Some(node_c);
                        (*node_c.as_ptr()).parent = Some(node_a);
                        (*node_a.as_ptr()).parent = Some(node_b);
                        (*fixed_head.as_ptr()).left = Some(node_b);
                    }
                }
            }
        }

        /// 2.3.1.1 remove black X
        ///
        /// ```text
        ///      A           B
        ///     / \         / \
        ///    B   X  =>   D   A
        ///   // \            /
        ///  D    C          C
        /// ```
        unsafe fn remove_black_leaf_2_3_1_1_balancing(&mut self, node_x: &NonNull<Node<T>>) {
            unsafe {
                let node_a = (*node_x.as_ptr()).parent.unwrap();
                if let Some(parent) = (*node_a.as_ptr()).parent {
                    let node_b = (*node_a.as_ptr()).left.unwrap();
                    let node_c = (*node_b.as_ptr()).right;
                    let node_d = (*node_b.as_ptr()).left.unwrap();
                    (*node_d.as_ptr()).is_red = false;
                    let mut node_a_from_left = false;
                    if let Some(p_node_a) = (*parent.as_ptr()).left
                        && std::ptr::eq(p_node_a.as_ptr(), node_a.as_ptr())
                    {
                        node_a_from_left = true;
                    }
                    (*node_b.as_ptr()).parent = Some(parent);
                    (*node_b.as_ptr()).right = Some(node_a);
                    (*node_a.as_ptr()).parent = Some(node_b);
                    (*node_a.as_ptr()).left = node_c;
                    if let Some(n_c) = node_c {
                        (*n_c.as_ptr()).parent = Some(node_a);
                    }
                    if node_a_from_left {
                        (*parent.as_ptr()).left = Some(node_b);
                    } else {
                        (*parent.as_ptr()).right = Some(node_b);
                    }
                } else {
                    // node_a is root
                    if let Some(fixed_head) = self.fixed_head {
                        let node_a = (*fixed_head.as_ptr()).left.unwrap();
                        let node_b = (*node_a.as_ptr()).left.unwrap();
                        let node_c = (*node_b.as_ptr()).right;
                        let node_d = (*node_b.as_ptr()).left.unwrap();
                        (*node_d.as_ptr()).is_red = false;
                        let node_b = (*node_a.as_ptr()).left.unwrap();
                        (*node_b.as_ptr()).parent = None;
                        (*node_b.as_ptr()).right = Some(node_a);
                        (*node_a.as_ptr()).parent = Some(node_b);
                        (*node_a.as_ptr()).left = node_c;
                        if let Some(n_c) = node_c {
                            (*n_c.as_ptr()).parent = Some(node_a);
                        }
                        (*fixed_head.as_ptr()).left = Some(node_b);
                    }
                }
            }
        }

        /// 2.3.1.2 remove black X
        ///
        /// ```text
        ///
        ///      A            D
        ///     / \         /   \
        ///    X   B  =>   A     B
        ///       //        \   /
        ///       D          C E
        ///      / \
        ///     C   E
        /// ```
        unsafe fn remove_black_leaf_2_3_1_2_balancing(&mut self, node_x: &NonNull<Node<T>>) {
            unsafe {
                let node_a = (*node_x.as_ptr()).parent.unwrap();
                if let Some(parent) = (*node_a.as_ptr()).parent {
                    let node_b = (*node_a.as_ptr()).right.unwrap();
                    let node_d = (*node_b.as_ptr()).left.unwrap();
                    let node_c = (*node_d.as_ptr()).left;
                    let node_e = (*node_d.as_ptr()).right;
                    (*node_d.as_ptr()).is_red = false;
                    let mut node_a_from_left = false;
                    if let Some(p_node_a) = (*parent.as_ptr()).left
                        && std::ptr::eq(p_node_a.as_ptr(), node_a.as_ptr())
                    {
                        node_a_from_left = true;
                    }
                    (*node_d.as_ptr()).parent = Some(parent);
                    (*node_d.as_ptr()).left = Some(node_a);
                    (*node_d.as_ptr()).right = Some(node_b);
                    (*node_a.as_ptr()).parent = Some(node_d);
                    (*node_b.as_ptr()).parent = Some(node_d);
                    (*node_a.as_ptr()).right = node_c;
                    if let Some(n_c) = node_c {
                        (*n_c.as_ptr()).parent = Some(node_a);
                    }
                    (*node_b.as_ptr()).left = node_e;
                    if let Some(n_e) = node_e {
                        (*n_e.as_ptr()).parent = Some(node_b);
                    }
                    if node_a_from_left {
                        (*parent.as_ptr()).left = Some(node_d);
                    } else {
                        (*parent.as_ptr()).right = Some(node_d);
                    }
                } else {
                    // node_a is root
                    if let Some(fixed_head) = self.fixed_head {
                        let node_a = (*fixed_head.as_ptr()).left.unwrap();
                        let node_b = (*node_a.as_ptr()).right.unwrap();
                        let node_d = (*node_b.as_ptr()).left.unwrap();
                        let node_c = (*node_d.as_ptr()).left;
                        let node_e = (*node_d.as_ptr()).right;
                        (*node_d.as_ptr()).is_red = false;
                        (*node_d.as_ptr()).parent = None;
                        (*node_d.as_ptr()).left = Some(node_a);
                        (*node_d.as_ptr()).right = Some(node_b);
                        (*node_a.as_ptr()).parent = Some(node_d);
                        (*node_b.as_ptr()).parent = Some(node_d);
                        (*node_a.as_ptr()).right = node_c;
                        if let Some(n_c) = node_c {
                            (*n_c.as_ptr()).parent = Some(node_a);
                        }
                        (*node_b.as_ptr()).left = node_e;
                        if let Some(n_e) = node_e {
                            (*n_e.as_ptr()).parent = Some(node_b);
                        }
                        (*fixed_head.as_ptr()).left = Some(node_d);
                    }
                }
            }
        }

        /// 2.3.2.1 remove black X
        ///
        /// ```text
        ///            P           P
        ///            |           |
        ///            A           A
        ///           / \   =>    //   => next check node A
        ///          B   X       B
        ///
        /// ```
        unsafe fn remove_black_leaf_2_3_2_1_balancing(
            &mut self,
            node_x: &NonNull<Node<T>>,
        ) -> NonNull<Node<T>> {
            unsafe {
                let node_a = (*node_x.as_ptr()).parent.unwrap();
                let node_b = (*node_a.as_ptr()).left.unwrap();
                (*node_b.as_ptr()).is_red = true;
                node_a
            }
        }

        /// 2.3.2.2 remove black X
        ///
        /// ```text
        ///              A            B
        ///             / \   =>    // \    =>  next check node B
        ///            X   B       A    D
        ///               / \       \
        ///              C   D       C
        /// ```
        unsafe fn remove_black_leaf_2_3_2_2_balancing(
            &mut self,
            node_x: &NonNull<Node<T>>,
        ) -> NonNull<Node<T>> {
            unsafe {
                let node_a = (*node_x.as_ptr()).parent.unwrap();
                (*node_a.as_ptr()).is_red = true;
                if let Some(parent) = (*node_a.as_ptr()).parent {
                    let node_b = (*node_a.as_ptr()).right.unwrap();
                    let node_c = (*node_b.as_ptr()).left;
                    let node_d = (*node_b.as_ptr()).right;
                    let mut node_a_from_left = false;
                    if let Some(p_node_a) = (*parent.as_ptr()).left
                        && std::ptr::eq(p_node_a.as_ptr(), node_a.as_ptr())
                    {
                        node_a_from_left = true;
                    }
                    (*node_b.as_ptr()).parent = Some(parent);
                    (*node_a.as_ptr()).right = node_c;
                    if let Some(n_c) = node_c {
                        (*n_c.as_ptr()).parent = Some(node_a);
                    }
                    (*node_b.as_ptr()).right = node_d;
                    if let Some(n_d) = node_d {
                        (*n_d.as_ptr()).parent = Some(node_b);
                    }
                    (*node_b.as_ptr()).left = Some(node_a);
                    (*node_a.as_ptr()).parent = Some(node_b);
                    if node_a_from_left {
                        (*parent.as_ptr()).left = Some(node_b);
                    } else {
                        (*parent.as_ptr()).right = Some(node_b);
                    }
                    node_b
                } else {
                    // node_a is root
                    if let Some(fixed_head) = self.fixed_head {
                        let node_a = (*fixed_head.as_ptr()).left.unwrap();
                        (*node_a.as_ptr()).is_red = true;
                        let node_b = (*node_a.as_ptr()).right.unwrap();
                        let node_c = (*node_b.as_ptr()).left;
                        let node_d = (*node_b.as_ptr()).right;
                        (*node_b.as_ptr()).parent = None;
                        (*node_a.as_ptr()).right = node_c;
                        if let Some(n_c) = node_c {
                            (*n_c.as_ptr()).parent = Some(node_a);
                        }
                        (*node_b.as_ptr()).right = node_d;
                        if let Some(n_d) = node_d {
                            (*n_d.as_ptr()).parent = Some(node_b);
                        }
                        (*node_b.as_ptr()).left = Some(node_a);
                        (*node_a.as_ptr()).parent = Some(node_b);
                        (*fixed_head.as_ptr()).left = Some(node_b);
                    }
                    self.get_root().unwrap()
                }
            }
        }

        unsafe fn remove_node(&mut self, node: NonNull<Node<T>>) -> bool {
            unsafe {
                match self.operation_remove(&node) {
                    OperationRemove::RedLeaf => {
                        // option 1.0.0
                        //
                        // ```text
                        //
                        //  P
                        //  ||
                        //  X
                        //
                        // ```

                        self.remove_leaf(node)
                    }
                    OperationRemove::BlackLeaf => {
                        // option 2 black leaf
                        self.remove_black_leaf(node)
                    }
                    OperationRemove::NodeWithChildren => {
                        // option 4.0.0
                        // ```text
                        //        X
                        //     /      \
                        //    L        R
                        //   / \      / \
                        // ...  C    L
                        //          /
                        //         C
                        //        ...
                        //
                        // ```
                        /*
                            The node has two children.

                            We take the predecessor:
                            the maximal node of the left subtree.

                            We only change the values,
                            then we delete the predecessor as a regular node.
                        */

                        let predecessor = self.find_max(node.as_ref().left.unwrap());

                        std::mem::swap(
                            &mut (*node.as_ptr()).value,
                            &mut (*predecessor.as_ptr()).value,
                        );

                        self.remove_node(predecessor)
                    }
                    OperationRemove::BlackNodeWithRedLeaf => {
                        // option 3.0.0
                        // ```text
                        //  X
                        // //
                        // A
                        // ```
                        let red_left = (*node.as_ptr()).left.unwrap();
                        std::mem::swap(&mut (*node.as_ptr()).value, &mut (*red_left.as_ptr()).value);
                        self.remove_leaf(red_left)
                    }
                }
            }
        }

        unsafe fn find_max(&self, node: NonNull<Node<T>>) -> NonNull<Node<T>> {
            unsafe {
                if node.as_ref().right.is_some() {
                    self.find_max(node.as_ref().right.unwrap())
                } else {
                    node
                }
            }
        }

        unsafe fn find_min(&self, node: NonNull<Node<T>>) -> NonNull<Node<T>> {
            unsafe {
                if node.as_ref().left.is_some() {
                    self.find_min(node.as_ref().left.unwrap())
                } else {
                    node
                }
            }
        }

        unsafe fn remove_leaf(&mut self, node: NonNull<Node<T>>) -> bool {
            unsafe {
                if let Some(mut parent) = node.as_ref().parent {
                    if let Some(ref mut left) = parent.as_mut().left {
                        if std::ptr::eq(left.as_ptr(), node.as_ptr()) {
                            parent.as_mut().left = None;
                        } else {
                            parent.as_mut().right = None;
                        }
                    } else {
                        parent.as_mut().right = None;
                    }
                }
                let _ = Box::from_raw(node.as_ptr());
                true
            }
        }

        unsafe fn remove_tree(&mut self, node: Link<T>) {
            unsafe {
                if let Some(node) = node {
                    self.remove_tree(node.as_ref().left);
                    self.remove_tree(node.as_ref().right);
                    if self.remove_leaf(node) {
                        assert!(self.count > 0);
                        self.count -= 1;
                    }
                }
            }
        }

        /// Rotate left and Rotate right and Flip color
        ///
        /// ```text
        ///             |              ||
        ///             P              C
        ///           //  \          /   \
        ///          A     F        A     P
        ///         / \\      =>   / \   / \
        ///        B   C          B   E D   F
        ///            / \
        ///           E   D
        /// ```
        unsafe fn rotate_left_right_flip_color(&mut self, node_a: NonNull<Node<T>>) -> Link<T> {
            unsafe {
                let node_p = (*node_a.as_ptr()).parent.unwrap();
                if let Some(parent) = (*node_p.as_ptr()).parent {
                    let mut node_p_from_left = false;
                    if let Some(p_node_p) = (*parent.as_ptr()).left
                        && std::ptr::eq(p_node_p.as_ptr(), node_p.as_ptr())
                    {
                        node_p_from_left = true;
                    }
                    let node_p = if node_p_from_left {
                        (*parent.as_ptr()).left.unwrap()
                    } else {
                        (*parent.as_ptr()).right.unwrap()
                    };
                    (*node_a.as_ptr()).is_red = false;
                    let node_c = (*node_a.as_ptr()).right.unwrap();
                    (*node_c.as_ptr()).is_red = false;
                    let node_e = (*node_c.as_ptr()).left;
                    let node_d = (*node_c.as_ptr()).right;
                    (*node_c.as_ptr()).is_red = true;
                    (*node_c.as_ptr()).parent = Some(parent);
                    (*node_c.as_ptr()).left = Some(node_a);
                    (*node_a.as_ptr()).parent = Some(node_c);
                    (*node_c.as_ptr()).right = Some(node_p);
                    (*node_p.as_ptr()).parent = Some(node_c);
                    (*node_p.as_ptr()).left = node_d;
                    if let Some(n_d) = node_d {
                        (*n_d.as_ptr()).parent = Some(node_p);
                    }
                    (*node_a.as_ptr()).right = node_e;
                    if let Some(n_e) = node_e {
                        (*n_e.as_ptr()).parent = Some(node_a);
                    }
                    if node_p_from_left {
                        (*parent.as_ptr()).left = Some(node_c);
                    } else {
                        (*parent.as_ptr()).right = Some(node_c);
                    }
                    Some(parent)
                } else {
                    let fixed_head = self.fixed_head.unwrap();
                    let node_p = (*fixed_head.as_ptr()).left.unwrap();

                    let node_a = (*node_p.as_ptr()).left.unwrap();
                    (*node_a.as_ptr()).is_red = false;
                    let node_c = (*node_a.as_ptr()).right.unwrap();
                    (*node_c.as_ptr()).is_red = false;
                    let node_e = (*node_c.as_ptr()).left;
                    let node_d = (*node_c.as_ptr()).right;
                    (*node_c.as_ptr()).is_red = false;
                    (*node_c.as_ptr()).parent = None;
                    (*node_c.as_ptr()).left = Some(node_a);
                    (*node_a.as_ptr()).parent = Some(node_c);
                    (*node_c.as_ptr()).right = Some(node_p);
                    (*node_p.as_ptr()).parent = Some(node_c);
                    (*node_p.as_ptr()).left = node_d;
                    if let Some(n_d) = node_d {
                        (*n_d.as_ptr()).parent = Some(node_p);
                    }
                    (*node_a.as_ptr()).right = node_e;
                    if let Some(n_e) = node_e {
                        (*n_e.as_ptr()).parent = Some(node_a);
                    }
                    (*fixed_head.as_ptr()).left = Some(node_c);
                    (*fixed_head.as_ptr()).left
                }
            }
        }

        /// Rotate left without parent
        /// A is root
        ///
        /// ```text
        ///             A                  C
        ///            / \\               //\
        ///           B    C     =>      A   D
        ///               / \           / \
        ///              E   D         B   E
        ///
        /// ```
        ///
        /// Rotate left  with parent
        ///
        /// ```text
        ///             P                  P
        ///             |                  |
        ///             A                  C
        ///            / \\               //\
        ///           B    C     =>      A   D
        ///               / \           / \
        ///              E   D         B   E
        ///
        /// ```
        unsafe fn rotate_left(&mut self, node_a: NonNull<Node<T>>) -> Link<T> {
            unsafe {
                if let Some(parent) = (*node_a.as_ptr()).parent {
                    let mut node_a_from_left = false;
                    if let Some(p_node_a) = (*parent.as_ptr()).left
                        && std::ptr::eq(p_node_a.as_ptr(), node_a.as_ptr())
                    {
                        node_a_from_left = true;
                    }
                    let node_a = if node_a_from_left {
                        (*parent.as_ptr()).left.unwrap()
                    } else {
                        (*parent.as_ptr()).right.unwrap()
                    };
                    let node_c = (*node_a.as_ptr()).right.unwrap();
                    (*node_c.as_ptr()).is_red = (*node_a.as_ptr()).is_red;
                    (*node_a.as_ptr()).is_red = true;
                    (*node_c.as_ptr()).parent = Some(parent);
                    if node_c.as_ref().left.is_some() {
                        let mut node_e = (*node_c.as_ptr()).left;
                        if let Some(e) = &mut node_e {
                            (*e.as_ptr()).parent = Some(node_a);
                        }
                        (*node_a.as_ptr()).right = node_e;
                    } else {
                        (*node_a.as_ptr()).right = None;
                    }
                    (*node_c.as_ptr()).left = Some(node_a);
                    (*node_a.as_ptr()).parent = Some(node_c);
                    if node_a_from_left {
                        (*parent.as_ptr()).left = Some(node_c);
                        (*parent.as_ptr()).left
                    } else {
                        (*parent.as_ptr()).right = Some(node_c);
                        (*parent.as_ptr()).right
                    }
                } else {
                    let fixed_head = self.fixed_head.unwrap();
                    let node_a = (*fixed_head.as_ptr()).left.unwrap();
                    let node_c = (*node_a.as_ptr()).right.unwrap();
                    (*node_c.as_ptr()).is_red = (*node_a.as_ptr()).is_red;
                    (*node_a.as_ptr()).is_red = true;
                    if node_c.as_ref().left.is_some() {
                        let mut node_e = (*node_c.as_ptr()).left;
                        if let Some(e) = &mut node_e {
                            (*e.as_ptr()).parent = Some(node_a);
                        }
                        (*node_a.as_ptr()).right = node_e;
                    } else {
                        (*node_a.as_ptr()).right = None;
                    }
                    (*node_c.as_ptr()).left = Some(node_a);
                    (*node_a.as_ptr()).parent = Some(node_c);
                    (*node_c.as_ptr()).parent = None;
                    (*fixed_head.as_ptr()).left = Some(node_c);
                    (*fixed_head.as_ptr()).left
                }
            }
        }

        /// Rotate right without parent
        /// A is root
        ///
        /// ```text
        ///              A               B
        ///            // \             / \\
        ///            B   C     =>    E    A
        ///          // \                  / \
        ///         E    D                D   C
        /// ```
        ///
        /// Rotate right with parent
        ///
        /// ```text
        ///                P               P
        ///                |               |
        ///                A               B
        ///              // \             / \\
        ///              B   C     =>    E    A
        ///            // \                  / \
        ///           E    D                D   C
        ///
        /// ```
        unsafe fn rotate_right(&mut self, node_a: NonNull<Node<T>>) -> Link<T> {
            unsafe {
                if let Some(parent) = (*node_a.as_ptr()).parent {
                    let mut node_a_from_left = false;
                    if let Some(p_node_a) = (*parent.as_ptr()).left
                        && std::ptr::eq(p_node_a.as_ptr(), node_a.as_ptr())
                    {
                        node_a_from_left = true;
                    }
                    let node_a = if node_a_from_left {
                        (*parent.as_ptr()).left.unwrap()
                    } else {
                        (*parent.as_ptr()).right.unwrap()
                    };
                    let node_b = (*node_a.as_ptr()).left.unwrap();
                    (*node_b.as_ptr()).parent = Some(parent);
                    (*node_b.as_ptr()).is_red = (*node_a.as_ptr()).is_red;
                    (*node_a.as_ptr()).is_red = true;
                    if node_b.as_ref().right.is_some() {
                        let mut node_d = (*node_b.as_ptr()).right;
                        if let Some(d) = &mut node_d {
                            (*d.as_ptr()).parent = Some(node_a);
                        }
                        (*node_a.as_ptr()).left = node_d;
                    } else {
                        (*node_a.as_ptr()).left = None;
                    }
                    (*node_b.as_ptr()).right = Some(node_a);
                    (*node_a.as_ptr()).parent = Some(node_b);
                    if node_a_from_left {
                        (*parent.as_ptr()).left = Some(node_b);
                        (*parent.as_ptr()).left
                    } else {
                        (*parent.as_ptr()).right = Some(node_b);
                        (*parent.as_ptr()).right
                    }
                } else {
                    let fixed_head = self.fixed_head.unwrap();
                    let node_a = (*fixed_head.as_ptr()).left.unwrap();
                    let node_b = (*node_a.as_ptr()).left.unwrap();
                    (*node_b.as_ptr()).is_red = (*node_a.as_ptr()).is_red;
                    (*node_a.as_ptr()).is_red = true;
                    if node_b.as_ref().right.is_some() {
                        let mut node_d = (*node_b.as_ptr()).right;
                        if let Some(d) = &mut node_d {
                            (*d.as_ptr()).parent = Some(node_a);
                        }
                        (*node_a.as_ptr()).left = node_d;
                    } else {
                        (*node_a.as_ptr()).left = None;
                    }
                    (*node_b.as_ptr()).right = Some(node_a);
                    (*node_a.as_ptr()).parent = Some(node_b);
                    (*node_b.as_ptr()).parent = None;
                    (*fixed_head.as_ptr()).left = Some(node_b);
                    (*fixed_head.as_ptr()).left
                }
            }
        }

        /// Flip color
        ///
        /// ```text
        ///             |          ||
        ///             A    =>    A
        ///           // \\       / \
        ///          B    C      B   C
        ///
        /// ```
        unsafe fn flip_colors(&mut self, mut node: NonNull<Node<T>>) {
            unsafe {
                if node.as_ref().left.is_some() && node.as_ref().right.is_some() {
                    if let Some(ref mut left) = node.as_mut().left {
                        left.as_mut().is_red = false;
                    }
                    if let Some(ref mut right) = node.as_mut().right {
                        right.as_mut().is_red = false;
                    }
                    node.as_mut().is_red = true;

                    if (*node.as_ptr()).parent.is_none() {
                        node.as_mut().is_red = false;
                    }
                }
            }
        }

        unsafe fn check_put_balancing(&mut self, node: NonNull<Node<T>>) -> OperationPut {
            unsafe {
                if node.as_ref().right.is_some() {
                    let r = node.as_ref().right.unwrap();
                    if node.as_ref().left.is_some() && !node.as_ref().is_red {
                        let l = node.as_ref().left.unwrap();
                        if l.as_ref().is_red && r.as_ref().is_red {
                            return OperationPut::FlipColors;
                        }
                    }
                    if r.as_ref().is_red {
                        return OperationPut::Left;
                    }
                }
                if node.as_ref().is_red && node.as_ref().left.is_some() {
                    let l = node.as_ref().left.unwrap();
                    if l.as_ref().is_red {
                        return OperationPut::Right;
                    }
                }
                OperationPut::Nothing
            }
        }

        unsafe fn put_balancing(&mut self, next: NonNull<Node<T>>) {
            unsafe {
                let mut next = next;
                loop {
                    match self.check_put_balancing(next) {
                        OperationPut::Left => {
                            if (*next.as_ptr()).is_red {
                                if let Some(n) = self.rotate_left_right_flip_color(next) {
                                    next = n;
                                }
                            } else {
                                if let Some(n) = self.rotate_left(next) {
                                    next = n;
                                }
                            }
                        }
                        OperationPut::Right => {
                            if (*next.as_ptr()).parent.is_some() {
                                let node_a = (*next.as_ptr()).parent.unwrap();
                                if let Some(n) = self.rotate_right(node_a) {
                                    next = n;
                                }
                            }
                        }
                        OperationPut::FlipColors => {
                            self.flip_colors(next);
                            if (*next.as_ptr()).parent.is_some() {
                                next = (*next.as_ptr()).parent.unwrap();
                            } else {
                                break;
                            }
                        }
                        OperationPut::Nothing => {
                            break;
                        }
                    }
                }
            }
        }

        unsafe fn find_put_parent_candidate(&mut self, parent: Link<T>, elem: &T) -> Link<T> {
            unsafe {
                if let Some(parent) = parent {
                    match elem.cmp(&parent.as_ref().value) {
                        Ordering::Equal => None,
                        Ordering::Less => {
                            if (*parent.as_ptr()).left.is_some() {
                                self.find_put_parent_candidate((*parent.as_ptr()).left, elem)
                            } else {
                                Some(parent)
                            }
                        }
                        Ordering::Greater => {
                            if (*parent.as_ptr()).right.is_some() {
                                self.find_put_parent_candidate((*parent.as_ptr()).right, elem)
                            } else {
                                Some(parent)
                            }
                        }
                    }
                } else {
                    parent
                }
            }
        }

        unsafe fn attach_node(&mut self, parent: NonNull<Node<T>>, elem: T) -> bool {
            unsafe {
                match elem.cmp(&parent.as_ref().value) {
                    Ordering::Equal => false,
                    Ordering::Less => {
                        (*parent.as_ptr()).left = Node::new_red(elem, parent);
                        true
                    }
                    Ordering::Greater => {
                        (*parent.as_ptr()).right = Node::new_red(elem, parent);
                        true
                    }
                }
            }
        }

        /// Returns the default iterator over the tree.
        ///
        /// The default traversal is in-order (`LNR`), so values are yielded in
        /// ascending order.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([3, 1, 2]);
        ///
        /// let values: Vec<i32> = tree.iter().copied().collect();
        ///
        /// assert_eq!(values, vec![1, 2, 3]);
        /// ```
        pub fn iter(&self) -> IterInOrder<'_, T> {
            self.iter_inorder()
        }

        /// Returns an in-order (`LNR`) iterator.
        ///
        /// Values are yielded in ascending order.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([3, 1, 2]);
        ///
        /// assert_eq!(
        ///     tree.iter_inorder().copied().collect::<Vec<_>>(),
        ///     vec![1, 2, 3]
        /// );
        /// ```
        pub fn iter_inorder(&self) -> IterInOrder<'_, T> {
            unsafe { IterInOrder::new(leftmost_child_in_order(self.get_root()), self.count) }
        }

        /// Returns a reverse in-order (`RNL`) iterator.
        ///
        /// Values are yielded in descending order.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([3, 1, 2]);
        ///
        /// assert_eq!(
        ///     tree.iter_reverse_inorder().copied().collect::<Vec<_>>(),
        ///     vec![3, 2, 1]
        /// );
        /// ```
        pub fn iter_reverse_inorder(&self) -> IterReverseInOrder<'_, T> {
            unsafe {
                IterReverseInOrder::new(
                    rightmost_child_reverse_in_order(self.get_root()),
                    self.count,
                )
            }
        }

        /// Returns a pre-order (`NLR`) iterator.
        ///
        /// The current node is visited before its left and right subtrees.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([4, 2, 6, 1, 3, 5, 7]);
        ///
        /// let values: Vec<i32> = tree.iter_preorder().copied().collect();
        ///
        /// assert_eq!(values.len(), tree.len());
        /// ```
        pub fn iter_preorder(&self) -> IterPreOrder<'_, T> {
            IterPreOrder::new(self.get_root(), self.count)
        }

        /// Returns a post-order (`LRN`) iterator.
        ///
        /// The left and right subtrees are visited before the current node.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([4, 2, 6, 1, 3, 5, 7]);
        ///
        /// let values: Vec<i32> = tree.iter_postorder().copied().collect();
        ///
        /// assert_eq!(values.len(), tree.len());
        /// ```
        pub fn iter_postorder(&self) -> IterPostOrder<'_, T> {
            unsafe {
                let first = self.get_root().map(|root| leaf_post_order(root));
                IterPostOrder::new(first, self.count)
            }
        }

        /// Returns all values in level-order traversal.
        ///
        /// Nodes are visited level by level, starting from the root.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([4, 2, 6, 1, 3, 5, 7]);
        ///
        /// let values = tree.iter_level_order();
        ///
        /// assert_eq!(values.len(), tree.len());
        /// ```
        pub fn iter_level_order(&self) -> Vec<&T> {
            let mut ret: Vec<&T> = vec![];
            if let Some(root) = self.get_root() {
                iter_level_order_impl(root, &mut ret);
            }
            ret
        }
    }

    impl<'a, T: Ord + Default> std::iter::IntoIterator for &'a RedBlackTree<T> {
        type IntoIter = IterInOrder<'a, T>;
        type Item = &'a T;

        fn into_iter(self) -> Self::IntoIter {
            self.iter()
        }
    }

    impl<T: Ord + Default> Drop for RedBlackTree<T> {
        fn drop(&mut self) {
            unsafe {
                if let Some(fixed_head) = self.fixed_head {
                    self.remove_tree((*fixed_head.as_ptr()).left);
                    let _ = Box::from_raw(fixed_head.as_ptr());
                }
                self.fixed_head = None;
            }
        }
    }

    fn find_node<T: Ord>(fromnode: Link<T>, value: &T) -> Link<T> {
        unsafe {
            if let Some(fromnode) = fromnode {
                match value.cmp(&(*fromnode.as_ptr()).value) {
                    Ordering::Equal => Some(fromnode),
                    Ordering::Less => find_node((*fromnode.as_ptr()).left, value),
                    Ordering::Greater => find_node((*fromnode.as_ptr()).right, value),
                }
            } else {
                fromnode
            }
        }
    }

    fn helper_display_tree<T: Display>(node: NonNull<Node<T>>) -> String {
        unsafe {
            let mut s: String = "".into();
            let color = if (*node.as_ptr()).is_red {
                "[color=\"red\"]"
            } else {
                "[color=\"black\"]"
            };

            if let Some(left) = (*node.as_ptr()).left {
                s.push_str(&format!(
                    "\t{n1}->{n2} {color1}; {n1} {color1}; {n2} {color2};\n",
                    n1 = (*node.as_ptr()).value,
                    n2 = (*left.as_ptr()).value,
                    color1 = color,
                    color2 = if (*left.as_ptr()).is_red {
                        "[color=\"red\"]"
                    } else {
                        "[color=\"black\"]"
                    },
                ));
                s.push_str(&helper_display_tree(left));
            } else if (*node.as_ptr()).right.is_some() {
                s.push_str(&format!(
                    "\t{n1}->node_null_{n1} [color=\"grey\"]; {n1} {color1};\n",
                    n1 = (*node.as_ptr()).value,
                    color1 = color
                ));
                s.push_str(&format!(
                    "\tnode_null_{n1}[label=\"null\"]\n",
                    n1 = (*node.as_ptr()).value
                ));
            }

            if let Some(right) = (*node.as_ptr()).right {
                s.push_str(&format!(
                    "\t{n1}->{n2} {color1}; {n1} {color1}; {n2} {color2};\n",
                    n1 = (*node.as_ptr()).value,
                    n2 = (*right.as_ptr()).value,
                    color2 = if (*right.as_ptr()).is_red {
                        "[color=\"red\"]"
                    } else {
                        "[color=\"black\"]"
                    },
                    color1 = color
                ));
                s.push_str(&helper_display_tree(right));
            } else {
                s.push_str(&format!(
                    "\t{n1}->node_null_{n1} [color=\"grey\"]; {n1} {color1};\n",
                    n1 = (*node.as_ptr()).value,
                    color1 = color
                ));
                s.push_str(&format!(
                    "\tnode_null_{}[label=\"null\"]\n",
                    (*node.as_ptr()).value
                ));
            }
            s
        }
    }

    impl<T: Ord + Default> Default for RedBlackTree<T> {
        fn default() -> Self {
            Self::new()
        }
    }

    impl<T: Ord + Default + Clone> Clone for RedBlackTree<T> {
        fn clone(&self) -> Self {
            let mut new_list = Self::new();
            for value in self {
                new_list.insert(value.clone());
            }
            new_list
        }
    }

    impl<T: Ord + Default> Extend<T> for RedBlackTree<T> {
        fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
            for value in iter {
                self.insert(value);
            }
        }
    }

    impl<T: Ord + Default> FromIterator<T> for RedBlackTree<T> {
        fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
            let mut list = Self::new();
            list.extend(iter);
            list
        }
    }

    impl<T: Ord + Default + Debug> Debug for RedBlackTree<T> {
        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
            f.debug_list().entries(self).finish()
        }
    }

    impl<T: Ord + Default> PartialEq for RedBlackTree<T> {
        fn eq(&self, other: &Self) -> bool {
            self.len() == other.len() && self.iter_inorder().eq(other.iter_inorder())
        }
    }

    impl<T: Ord + Default> Eq for RedBlackTree<T> {}

    impl<T: Ord + Default> PartialOrd for RedBlackTree<T> {
        fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
            Some(self.cmp(other))
        }
    }

    impl<T: Ord + Default> Ord for RedBlackTree<T> {
        fn cmp(&self, other: &Self) -> Ordering {
            self.iter_inorder().cmp(other.iter_inorder())
        }
    }

    impl<T: Ord + Default + std::hash::Hash> std::hash::Hash for RedBlackTree<T> {
        fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
            self.len().hash(state);
            for item in self {
                item.hash(state);
            }
        }
    }
}

5. Приоритетная очередь (Priority queue)

Priority queue с возможностью удаления произвольного элемента. В отличие от heap, Red-Black Tree позволяет не только взять min/max, но и удалить конкретный элемент. Например: задачи по приоритету, таймеры, scheduler events

Преимущество перед heap: мы можем удалить конкретную задачу до того, как она станет самой приоритетной.

Очередь задач:

priority 10  → Send email
priority 50  → Generate report
priority 100 → Fix production
priority 80  → Deploy release
use std::cmp::Ordering;

#[derive(Debug, Default)]
struct Task {
    id: u32,
    priority: u32,
    name: String,
}
// Две задачи считаются одинаковыми, если совпадают priority и id.
impl PartialEq for Task {
    fn eq(&self, other: &Self) -> bool {
        self.priority == other.priority && self.id == other.id
    }
}
impl Eq for Task {}
impl PartialOrd for Task {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}
// Сначала сортируем по priority. id нужен как дополнительный ключ,
// чтобы задачи с одинаковым приоритетом не считались одинаковыми.
impl Ord for Task {
    fn cmp(&self, other: &Self) -> Ordering {
        self.priority
            .cmp(&other.priority)
            .then_with(|| self.id.cmp(&other.id))
    }
}
fn main() {
    let mut queue = RedBlackTree::new();
    queue.insert(Task {
        id: 1,
        priority: 10,
        name: "Send email".into(),
    });
    queue.insert(Task {
        id: 2,
        priority: 50,
        name: "Generate report".into(),
    });
    queue.insert(Task {
        id: 3,
        priority: 100,
        name: "Fix production".into(),
    });
    queue.insert(Task {
        id: 4,
        priority: 80,
        name: "Deploy release".into(),
    });
    println!("Очередь по приоритету:");
    for task in queue.iter() {
        println!(
            "priority={} id={} task={}",
            task.priority,
            task.id,
            task.name
        );
    }
    // Задачу id=4 отменили до выполнения.
    let cancelled = Task {
        id: 4,
        priority: 80,
        name: String::new(),
    };

    queue.remove(&cancelled);

    println!("\nПосле отмены Deploy release:");
    for task in queue.iter() {
        println!(
            "priority={} id={} task={}",
            task.priority,
            task.id,
            task.name
        );
    }
    println!("\nВыполняем задачи от самой важной к менее важной:");
    while let Some(task) = queue.pop_last() {
        println!(
            "priority={} id={} task={}",
            task.priority,
            task.id,
            task.name
        );
    }
}














/// -------------------------------------------
/// Implementation RBT
/// -------------------------------------------


pub use tree::RedBlackTree;
pub use iter::{IterInOrder, Range};
pub use iter::IterPreOrder;
pub use iter::IterReverseInOrder;
pub use iter::IterPostOrder;
 
pub mod iter{
    use std::ptr::NonNull;

    use crate::node::{Link, Node};

    ///```text
    ///
    ///            4
    ///          /   \
    ///         2     9
    ///        / \   //\
    ///       1   3  7   10
    ///             / \
    ///            6   8
    ///```
    ///    Depth-First Search / Pre-order (NLR):     4, 2, 1, 3, 9, 7, 6, 8, 10
    ///    Depth-First Search / In-order (LNR):      1, 2, 3, 4, 6, 7, 8, 9, 10
    ///    Depth-First Search / Post-order (LRN):    1, 3, 2, 6, 8, 7, 10, 9, 4
    ///    Breadth-First Search / Level-order:       4, 2, 9, 1, 3, 7, 10, 6, 8 
    pub use dfs_in_order::{IterInOrder, Range};

    pub(crate) use dfs_in_order::{leftmost_child_in_order, successor_of_node_in_order};

    mod dfs_in_order {
        use super::{Link, Node, NonNull};
        use std::iter::FusedIterator;
        use std::marker::PhantomData;

        /// Returns the next node in an in-order (`LNR`) traversal.
        ///
        /// # Safety
        ///
        /// `node` must point to a live node that belongs to the current tree, and
        /// all parent/child links reachable from it must be valid.
        pub unsafe fn successor_of_node_in_order<T>(node: NonNull<Node<T>>) -> Link<T> {
            unsafe {
                if node.as_ref().right.is_some() {
                    // If a right subtree exists, the successor is its leftmost node.
                    leftmost_child_in_order(node.as_ref().right)
                } else {
                    // Otherwise, walk up through parent links until the current
                    // node is found in a left subtree.
                    parent_with_left(node)
                }
            }
        }

        /// Returns the leftmost node reachable from `node`.
        ///
        /// Returns `None` when `node` is `None`.
        ///
        /// # Safety
        ///
        /// Every pointer reachable through `left` links must refer to a live node.
        pub unsafe fn leftmost_child_in_order<T>(node: Link<T>) -> Link<T> {
            unsafe {
                if let Some(node) = node {
                    if node.as_ref().left.is_none() {
                        Some(node)
                    } else {
                        leftmost_child_in_order(node.as_ref().left)
                    }
                } else {
                    node
                }
            }
        }

        /// Walks up the parent chain until an ancestor is reached from its left child.
        ///
        /// # Safety
        ///
        /// `node` and all parent links traversed by this function must be valid.
        unsafe fn parent_with_left<T>(node: NonNull<Node<T>>) -> Link<T> {
            unsafe {
                let parent = node.as_ref().parent;
                if let Some(parent) = parent
                    && let Some(left) = parent.as_ref().left
                {
                    if std::ptr::eq(left.as_ptr(), node.as_ptr()) {
                        return Some(parent);
                    }
                    return parent_with_left(parent);
                }
                // No parent means that the root has been reached.
                None
            }
        }

        /// Iterator over a tree in in-order (`Left -> Node -> Right`, or `LNR`).
        ///
        /// For a binary search tree, this traversal yields values in ascending order.
        pub struct IterInOrder<'a, T> {
            current_node: Link<T>,
            count: usize,
            elem: Option<&'a T>,
            _boo: PhantomData<&'a T>,
        }

        impl<'a, T> IterInOrder<'a, T> {
            /// Creates an in-order iterator starting at `node`.
            pub(crate) fn new(node: Link<T>, count: usize) -> Self {
                Self {
                    current_node: node,
                    count,
                    elem: None,
                    _boo: PhantomData,
                }
            }
        }

        impl<'a, T> Iterator for IterInOrder<'a, T> {
            type Item = &'a T;

            fn next(&mut self) -> Option<Self::Item> {
                if self.count > 0 {
                    self.count -= 1;
                    if let Some(node) = self.current_node {
                        unsafe {
                            self.elem = Some(&node.as_ref().value);
                            self.current_node = successor_of_node_in_order(node);
                        }
                    } else {
                        self.elem = None;
                    }
                } else {
                    self.elem = None;
                }
                self.elem
            }

            fn size_hint(&self) -> (usize, Option<usize>) {
                (self.count, Some(self.count))
            }
        }

        impl<'a, T> ExactSizeIterator for IterInOrder<'a, T> {
            fn len(&self) -> usize {
                self.count
            }
        }

        impl<'a, T> FusedIterator for IterInOrder<'a, T> {}

        /// A lazy iterator over an inclusive range of values in a [`crate::RedBlackTree`].
        ///
        /// `Range` is created by [`crate::RedBlackTree::range`]. It yields references to
        /// values in ascending order, starting from the first value greater than or
        /// equal to the lower bound and stopping after the upper bound.
        ///
        /// The iterator does not allocate an intermediate collection. Values are
        /// produced one at a time as the iterator advances.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([1, 3, 5, 7, 9, 11]);
        ///
        /// let values: Vec<_> = tree
        ///     .range(&3, &9)
        ///     .copied()
        ///     .collect();
        ///
        /// assert_eq!(values, vec![3, 5, 7, 9]);
        /// ```
        ///
        /// The iterator can be combined with standard iterator adapters:
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend(1..=100);
        ///
        /// let values: Vec<_> = tree
        ///     .range(&20, &80)
        ///     .take(3)
        ///     .copied()
        ///     .collect();
        ///
        /// assert_eq!(values, vec![20, 21, 22]);
        /// ```
        pub struct Range<'a, T> {
            current_node: Link<T>,
            end_node: Link<T>,
            _marker: PhantomData<&'a T>,
        }

        impl<'a, T: Ord> Range<'a, T> {
            pub(crate) fn new(root: Link<T>, min: &T, max: &T) -> Self {
                if min > max {
                    return Self {
                        current_node: None,
                        end_node: None,
                        _marker: PhantomData,
                    };
                }

                unsafe {
                    let mut current = root;
                    let mut start: Link<T> = None;

                    // First node >= min.
                    while let Some(node) = current {
                        match node.as_ref().value.cmp(min) {
                            std::cmp::Ordering::Less => {
                                current = node.as_ref().right;
                            }

                            std::cmp::Ordering::Equal => {
                                start = Some(node);
                                break;
                            }

                            std::cmp::Ordering::Greater => {
                                start = Some(node);
                                current = node.as_ref().left;
                            }
                        }
                    }

                    current = root;

                    let mut end: Link<T> = None;

                    // First node > max.
                    while let Some(node) = current {
                        match node.as_ref().value.cmp(max) {
                            std::cmp::Ordering::Less | std::cmp::Ordering::Equal => {
                                current = node.as_ref().right;
                            }

                            std::cmp::Ordering::Greater => {
                                end = Some(node);
                                current = node.as_ref().left;
                            }
                        }
                    }

                    Self {
                        current_node: start,
                        end_node: end,
                        _marker: PhantomData,
                    }
                }
            }
        }

        impl<'a, T> Iterator for Range<'a, T> {
            type Item = &'a T;

            fn next(&mut self) -> Option<Self::Item> {
                let node = self.current_node?;

                if self.end_node == Some(node) {
                    self.current_node = None;
                    return None;
                }

                unsafe {
                    let value = &node.as_ref().value;

                    self.current_node = successor_of_node_in_order(node);

                    Some(value)
                }
            }
        }
    }

    pub use dfs_reverse_in_order::IterReverseInOrder;

    pub(crate) use dfs_reverse_in_order::{
        rightmost_child_reverse_in_order, successor_of_node_reverse_in_order,
    };

    mod dfs_reverse_in_order {
        use super::{Link, Node, NonNull};
        use std::marker::PhantomData;

        /// Returns the next node in reverse in-order (`Right -> Node -> Left`, or `RNL`).
        ///
        /// # Safety
        ///
        /// `node` must point to a live node that belongs to the current tree, and
        /// all parent/child links reachable from it must be valid.
        pub unsafe fn successor_of_node_reverse_in_order<T>(node: NonNull<Node<T>>) -> Link<T> {
            unsafe {
                if node.as_ref().left.is_some() {
                    // After the current node, descend into the left subtree and
                    // choose its rightmost node.
                    rightmost_child_reverse_in_order(node.as_ref().left)
                } else {
                    // Without a left subtree, walk upward until reaching an
                    // ancestor from its right subtree.
                    parent_with_right(node)
                }
            }
        }

        /// Returns the rightmost node reachable from `node`.
        ///
        /// Returns `None` when `node` is `None`.
        ///
        /// # Safety
        ///
        /// Every pointer reachable through `right` links must refer to a live node.
        pub unsafe fn rightmost_child_reverse_in_order<T>(node: Link<T>) -> Link<T> {
            unsafe {
                if let Some(node) = node {
                    if node.as_ref().right.is_none() {
                        Some(node)
                    } else {
                        rightmost_child_reverse_in_order(node.as_ref().right)
                    }
                } else {
                    None
                }
            }
        }

        /// Walks up the parent chain until an ancestor is reached from its right child.
        ///
        /// # Safety
        ///
        /// `node` and all parent links traversed by this function must be valid.
        unsafe fn parent_with_right<T>(node: NonNull<Node<T>>) -> Link<T> {
            unsafe {
                let parent = node.as_ref().parent;

                if let Some(parent) = parent
                    && let Some(right) = parent.as_ref().right
                {
                    if std::ptr::eq(right.as_ptr(), node.as_ptr()) {
                        return Some(parent);
                    }

                    return parent_with_right(parent);
                }

                None
            }
        }

        /// Iterator over a tree in reverse in-order (`Right -> Node -> Left`, or `RNL`).
        ///
        /// For a binary search tree, this traversal yields values in descending order.
        pub struct IterReverseInOrder<'a, T> {
            current_node: Link<T>,
            count: usize,
            elem: Option<&'a T>,
            _boo: PhantomData<&'a T>,
        }

        impl<'a, T> IterReverseInOrder<'a, T> {
            /// Creates a reverse in-order iterator starting at `node`.
            pub(crate) fn new(node: Link<T>, count: usize) -> Self {
                Self {
                    current_node: node,
                    count,
                    elem: None,
                    _boo: PhantomData,
                }
            }
        }

        impl<'a, T> Iterator for IterReverseInOrder<'a, T> {
            type Item = &'a T;

            fn next(&mut self) -> Option<Self::Item> {
                if self.count > 0 {
                    self.count -= 1;

                    if let Some(node) = self.current_node {
                        unsafe {
                            self.elem = Some(&node.as_ref().value);
                            self.current_node = successor_of_node_reverse_in_order(node);
                        }
                    } else {
                        self.elem = None;
                    }
                } else {
                    self.elem = None;
                }

                self.elem
            }

            fn size_hint(&self) -> (usize, Option<usize>) {
                (self.count, Some(self.count))
            }
        }
    }

    pub use dfs_pre_order::IterPreOrder;

    pub(crate) use dfs_pre_order::successor_of_node_pre_order;

    mod dfs_pre_order {
        use super::{Link, Node, NonNull};
        use std::marker::PhantomData;

        /// Returns the next node in a pre-order (`Node -> Left -> Right`, or `NLR`) traversal.
        ///
        /// # Safety
        ///
        /// `node` must point to a live node in the current tree and all traversed
        /// links must be valid.
        pub unsafe fn successor_of_node_pre_order<T>(node: NonNull<Node<T>>) -> Link<T> {
            unsafe {
                if let Some(node) = node.as_ref().left {
                    Some(node)
                } else if let Some(node) = node.as_ref().right {
                    Some(node)
                } else {
                    right_with_parent(node)
                }
            }
        }

        /// Finds the next right subtree by walking through parent links.
        ///
        /// # Safety
        ///
        /// `node` and all parent links traversed by this function must be valid.
        unsafe fn right_with_parent<T>(node: NonNull<Node<T>>) -> Link<T> {
            unsafe {
                if let Some(parent) = node.as_ref().parent {
                    next_right(Some(parent), node)
                } else {
                    None
                }
            }
        }

        /// Searches ancestors for the next unvisited right child.
        ///
        /// # Safety
        ///
        /// `child`, `node`, and all links traversed by this function must be valid.
        unsafe fn next_right<T>(node: Link<T>, child: NonNull<Node<T>>) -> Link<T> {
            unsafe {
                if let Some(n) = node {
                    if let Some(right) = n.as_ref().right {
                        if std::ptr::eq(right.as_ptr(), child.as_ptr()) {
                            next_right(n.as_ref().parent, n)
                        } else {
                            Some(right)
                        }
                    } else {
                        next_right(n.as_ref().parent, n)
                    }
                } else {
                    None
                }
            }
        }

        /// Iterator over a tree in pre-order (`Node -> Left -> Right`, or `NLR`).
        ///
        /// Pre-order traversal visits a node before either of its subtrees.
        pub struct IterPreOrder<'a, T> {
            current_node: Link<T>,
            count: usize,
            elem: Option<&'a T>,
            _boo: PhantomData<&'a T>,
        }

        impl<'a, T> IterPreOrder<'a, T> {
            /// Creates a pre-order iterator starting at `root`.
            pub(crate) fn new(root: Link<T>, count: usize) -> Self {
                Self {
                    current_node: root,
                    count,
                    elem: None,
                    _boo: PhantomData,
                }
            }
        }

        impl<'a, T> Iterator for IterPreOrder<'a, T> {
            type Item = &'a T;

            fn next(&mut self) -> Option<Self::Item> {
                if self.count > 0 {
                    self.count -= 1;
                    if let Some(node) = self.current_node {
                        unsafe {
                            self.elem = Some(&node.as_ref().value);
                            self.current_node = successor_of_node_pre_order(node);
                        }
                    } else {
                        self.elem = None;
                    }
                } else {
                    self.elem = None;
                }
                self.elem
            }

            fn size_hint(&self) -> (usize, Option<usize>) {
                (self.count, Some(self.count))
            }
        }
    }

    pub use dfs_post_order::IterPostOrder;

    pub(crate) use dfs_post_order::{leaf_post_order, successor_of_node_post_order};

    mod dfs_post_order {
        use super::{Link, Node, NonNull};
        use std::marker::PhantomData;

        /// Returns the next node in a post-order (`Left -> Right -> Node`, or `LRN`) traversal.
        ///
        /// # Safety
        ///
        /// `current_node` must point to a live node in the current tree and all
        /// traversed parent/child links must be valid.
        pub unsafe fn successor_of_node_post_order<T>(current_node: NonNull<Node<T>>) -> Link<T> {
            unsafe {
                if let Some(parent) = current_node.as_ref().parent {
                    if let Some(right) = parent.as_ref().right {
                        if std::ptr::eq(current_node.as_ptr(), right.as_ptr()) {
                            Some(parent)
                        } else {
                            Some(leaf_post_order(right))
                        }
                    } else {
                        Some(parent)
                    }
                } else {
                    None
                }
            }
        }

        /// Returns the first leaf visited by a post-order traversal starting at `node`.
        ///
        /// # Safety
        ///
        /// `node` must point to a live node and all descendant links traversed by
        /// this function must be valid.
        pub unsafe fn leaf_post_order<T>(node: NonNull<Node<T>>) -> NonNull<Node<T>> {
            unsafe {
                if let Some(left) = node.as_ref().left {
                    leaf_post_order(left)
                } else if let Some(right) = node.as_ref().right {
                    leaf_post_order(right)
                } else {
                    node
                }
            }
        }

        /// Iterator over a tree in post-order (`Left -> Right -> Node`, or `LRN`).
        ///
        /// Post-order traversal visits both subtrees before the current node.
        pub struct IterPostOrder<'a, T> {
            current_node: Link<T>,
            count: usize,
            _boo: PhantomData<&'a T>,
        }

        impl<'a, T> IterPostOrder<'a, T> {
            /// Creates a post-order iterator starting at the first post-order node.
            pub(crate) fn new(root: Link<T>, count: usize) -> Self {
                Self {
                    current_node: root,
                    count,
                    _boo: PhantomData,
                }
            }
        }

        impl<'a, T> Iterator for IterPostOrder<'a, T> {
            type Item = &'a T;

            fn next(&mut self) -> Option<Self::Item> {
                if self.count == 0 {
                    return None;
                }

                let node = self.current_node?;

                unsafe {
                    let value = &node.as_ref().value;
                    self.current_node = successor_of_node_post_order(node);
                    self.count -= 1;
                    Some(value)
                }
            }

            fn size_hint(&self) -> (usize, Option<usize>) {
                (self.count, Some(self.count))
            }
        }
    }

    /// Breadth-First Search
    mod bfs {
        use super::{Node, NonNull};
        use std::collections::VecDeque;

        /// Appends tree values to `ret` in breadth-first / level-order.
        pub fn iter_level_order_impl<T>(root: NonNull<Node<T>>, ret: &mut Vec<&T>) {
            let mut deque: VecDeque<NonNull<Node<T>>> = VecDeque::new();
            unsafe {
                deque.push_back(root);
                let mut node: NonNull<Node<T>>;
                while !deque.is_empty() {
                    node = deque.pop_front().unwrap();
                    ret.push(&node.as_ref().value);
                    if let Some(left) = node.as_ref().left {
                        deque.push_back(left);
                    }
                    if let Some(right) = node.as_ref().right {
                        deque.push_back(right);
                    }
                }
            }
        }
    }

    pub(crate) use bfs::iter_level_order_impl;
}

/// Internal node representation used by the Red-Black Tree.
///
/// Nodes are allocated on the heap and connected using [`NonNull`] pointers.
/// The tree owns the allocated nodes and is responsible for releasing them.
///
/// `Node` and [`Link`] are crate-private implementation details and are not
/// exposed through the public API.
pub mod node{

    use std::ptr::NonNull;

    /// A single node in the Red-Black Tree.
    ///
    /// Each node stores:
    ///
    /// - a link to its left child;
    /// - a link to its right child;
    /// - a link to its parent;
    /// - its Red-Black color;
    /// - the stored value.
    ///
    /// Tree links are represented by [`Link<T>`], which is an
    /// `Option<NonNull<Node<T>>>`.
    ///
    /// A `None` link represents the absence of a parent or child, while
    /// `Some(pointer)` refers to another allocated node.
    ///
    /// Memory ownership is managed by [`crate::RedBlackTree`]. The pointers stored
    /// here are non-owning links between nodes.
    #[derive(Debug)]
    pub(crate) struct Node<T> {
        /// Left child of this node.
        pub(crate) left: Link<T>,

        /// Right child of this node.
        pub(crate) right: Link<T>,

        /// Parent of this node.
        ///
        /// The root node has no parent.
        pub(crate) parent: Link<T>,

        /// Red-Black color of the node.
        ///
        /// `true` means red and `false` means black.
        pub(crate) is_red: bool,

        /// Value stored in this node.
        pub(crate) value: T,
    }

    /// A link between nodes in the tree.
    ///
    /// `None` represents a missing parent or child.
    ///
    /// `Some(ptr)` contains a non-null pointer to another allocated [`Node`].
    ///
    /// Using `Option<NonNull<Node<T>>>` allows the implementation to represent
    /// nullable tree links while keeping direct pointer-based navigation between
    /// parents and children.
    pub(crate) type Link<T> = Option<NonNull<Node<T>>>;

    impl<T: Default> Node<T> {
        /// Creates the sentinel head node together with the initial tree root.
        ///
        /// The sentinel does not represent a value stored by the user. Its
        /// `value` field is initialized with [`Default::default`] and its left
        /// child becomes the first actual node in the tree.
        ///
        /// The initial root node is created as black, as required by the
        /// Red-Black Tree invariants.
        ///
        /// # Returns
        ///
        /// A link to the newly allocated sentinel node.
        ///
        /// # Implementation
        ///
        /// Both the sentinel and the root node are allocated on the heap.
        /// Ownership of these allocations is transferred to the tree and later
        /// recovered when the tree releases its nodes.
        pub(crate) fn new_fixed_head(value: T) -> Link<T> {
            let fixed_head = Box::into_non_null(Box::new(Self {
                left: None,
                right: None,
                parent: None,
                is_red: false,
                value: T::default(),
            }));
            unsafe {
                (*fixed_head.as_ptr()).left = Node::new_black(value);
            }
            Some(fixed_head)
        }
    }

    impl<T> Node<T> {
        /// Allocates a new black node.
        ///
        /// The node is created without a parent or children.
        ///
        /// # Returns
        ///
        /// A non-null link to the newly allocated node.
        ///
        /// The allocation becomes owned by the tree and must eventually be
        /// released by the tree implementation.
        pub(crate) fn new_black(value: T) -> Link<T> {
            let new = Box::into_non_null(Box::new(Self {
                left: None,
                right: None,
                parent: None,
                is_red: false,
                value,
            }));

            Some(new)
        }

        /// Allocates a new red node with the specified parent.
        ///
        /// Newly inserted Red-Black Tree nodes are initially red. The balancing
        /// algorithm may later recolor the node or rotate the surrounding
        /// subtree.
        ///
        /// The new node has no children.
        ///
        /// # Parameters
        ///
        /// - `value` — value stored in the node.
        /// - `parent` — non-null pointer to the node's parent.
        ///
        /// # Returns
        ///
        /// A non-null link to the newly allocated node.
        ///
        /// The allocation becomes owned by the tree and must eventually be
        /// released by the tree implementation.
        pub(crate) fn new_red(value: T, parent: NonNull<Node<T>>) -> Link<T> {
            let new = Box::into_non_null(Box::new(Self {
                left: None,
                right: None,
                parent: Some(parent),
                is_red: true,
                value,
            }));

            Some(new)
        }
    }
}


pub mod validation{
    use crate::node::Link;
    use crate::tree::RedBlackTree;

    impl<T: Ord + Default> RedBlackTree<T> {
        // red-red violations,
        // min black-height,
        // max black-height,
        // BST ordering,
        // parent links,
        // reachable node count
        unsafe fn validate(
            node: &Link<T>,
            expected_parent: Link<T>,
            parent_is_red: bool,
            black_height: usize,
            min: Option<&T>,
            max: Option<&T>,
        ) -> (usize, usize, usize, bool, bool, usize) {
            unsafe {
                if let Some(n) = node {
                    let value = &n.as_ref().value;

                    // 1. Check parent
                    let parent_valid = match (n.as_ref().parent, expected_parent) {
                        (None, None) => true,

                        (Some(actual), Some(expected)) => {
                            std::ptr::eq(actual.as_ptr(), expected.as_ptr())
                        }

                        _ => false,
                    };

                    // 2. Check BST ordering
                    if let Some(min) = min
                        && value <= min
                    {
                        return (0, 0, 0, false, parent_valid, 1);
                    }

                    if let Some(max) = max
                        && value >= max
                    {
                        return (0, 0, 0, false, parent_valid, 1);
                    }

                    let is_red = n.as_ref().is_red;

                    // 3. A red node cannot have a red parent.
                    let red_red = if parent_is_red && is_red { 1 } else { 0 };

                    // 4. Black height
                    let black_height = if is_red {
                        black_height
                    } else {
                        black_height + 1
                    };

                    let left = Self::validate(
                        &n.as_ref().left,
                        Some(*n),
                        is_red,
                        black_height,
                        min,
                        Some(value),
                    );

                    let right = Self::validate(
                        &n.as_ref().right,
                        Some(*n),
                        is_red,
                        black_height,
                        Some(value),
                        max,
                    );

                    (
                        red_red + left.0 + right.0,
                        std::cmp::min(left.1, right.1),
                        std::cmp::max(left.2, right.2),
                        left.3 && right.3,
                        parent_valid && left.4 && right.4,
                        1 + left.5 + right.5,
                    )
                } else {
                    (0, black_height, black_height, true, true, 0)
                }
            }
        }

        pub fn is_valid(&self) -> bool {
            unsafe {
                // tree is empty
                if self.count == 0 {
                    return match self.fixed_head {
                        None => true,

                        Some(fixed_head) => (*fixed_head.as_ptr()).left.is_none(),
                    };
                }

                // count > 0, so sentinel must exist.
                let Some(fixed_head) = self.fixed_head else {
                    return false;
                };

                // And root must exist.
                let root_link = (*fixed_head.as_ptr()).left;

                let Some(root) = root_link else {
                    return false;
                };

                // Root is always BLACK
                if root.as_ref().is_red {
                    return false;
                }

                // Root has no parent
                if root.as_ref().parent.is_some() {
                    return false;
                }

                let result = Self::validate(&root_link, None, false, 0, None, None);

                let red_red = result.0;
                let black_height_min = result.1;
                let black_height_max = result.2;
                let bst_valid = result.3;
                let parents_valid = result.4;
                let reachable_nodes = result.5;

                red_red == 0
                    && black_height_min == black_height_max
                    && bst_valid
                    && parents_valid
                    && reachable_nodes == self.count
            }
        }
    }
}


pub mod tree{
    use std::cmp::Ordering;
    use std::fmt::{Debug, Display};

    use crate::node::{Link, Node};

    use std::marker::PhantomData;
    use std::ptr::NonNull;

    use crate::iter::{IterInOrder, Range, leftmost_child_in_order, successor_of_node_in_order};

    use crate::iter::{
        IterReverseInOrder, rightmost_child_reverse_in_order, successor_of_node_reverse_in_order,
    };

    use crate::iter::{IterPreOrder, successor_of_node_pre_order};

    use crate::iter::{IterPostOrder, leaf_post_order, successor_of_node_post_order};

    use crate::iter::iter_level_order_impl;

    /// A self-balancing Red-Black Tree.
    ///
    /// `RedBlackTree` stores unique values in sorted order.
    ///
    /// Insert, lookup and removal operations have logarithmic
    /// expected tree height due to Red-Black Tree balancing.
    ///
    /// # Examples
    ///
    /// ```
    /// use rbtree_extended::RedBlackTree;
    ///
    /// let mut tree = RedBlackTree::new();
    ///
    /// tree.insert(3);
    /// tree.insert(1);
    /// tree.insert(2);
    ///
    /// assert_eq!(tree.len(), 3);
    /// assert!(tree.contains(&2));
    /// ```
    pub struct RedBlackTree<T: Ord + Default> {
        pub(crate) fixed_head: Link<T>,
        pub(crate) count: usize,
        _marker: PhantomData<T>,
    }

    enum OperationPut {
        Left,
        Right,
        FlipColors,
        Nothing,
    }

    enum OperationRemove {
        RedLeaf,
        BlackLeaf,
        NodeWithChildren,
        BlackNodeWithRedLeaf,
    }

    enum OperationRemoveBlackLeaf {
        LeftRedABlackBRedCleaf,                      // 2.1.1.1
        RightRedABlackBRedCleaf,                     // 2.1.1.2
        LeftRedABlackBleaf,                          // 2.1.2.1
        RightRedABlackBleaf,                         // 2.1.2.2
        BlackARedBWithBlackChildrenLeaf,             // 2.2.4
        BlackARedBWithBlackChildrenRightHaveRedLeaf, // 2.2.1
        BlackALeftBlackBRedDleaf,                    // 2.3.1.1
        BlackARightBlackBRedDleaf,                   // 2.3.1.2
        BlackALeftBlackBleaf,                        // 2.3.2.1
        BlackARightBlackBleaf,                       // 2.3.2.2
        Root,
        Unimplemented,
    }

    impl<T: Ord + Default + Display> RedBlackTree<T> {
        /// Exports the tree in Graphviz DOT format.
        ///
        /// The returned string can be rendered using Graphviz-compatible tools.
        ///
        /// An empty tree produces a valid empty DOT graph.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.insert(10);
        /// tree.insert(5);
        /// tree.insert(20);
        ///
        /// let dot = tree.to_dot();
        ///
        /// println!("{dot}");
        /// ```
        pub fn to_dot(&self) -> String {
            unsafe {
                let Some(fixed_head) = self.fixed_head else {
                    return "digraph Tree {}".into();
                };

                let Some(root) = (*fixed_head.as_ptr()).left else {
                    return "digraph Tree {}".into();
                };

                format!(
                    "\ndigraph Tree {{\n\tratio = fill;\n\tnode [style=filled fontcolor=\"white\"];\n{}}}",
                    helper_display_tree(root)
                )
            }
        }
    }

    impl<T: Ord + Default> RedBlackTree<T> {
        /// Creates an empty Red-Black Tree.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let tree = RedBlackTree::<i32>::new();
        ///
        /// assert!(tree.is_empty());
        /// ```
        pub fn new() -> Self {
            Self {
                fixed_head: None,
                count: 0,
                _marker: PhantomData,
            }
        }

        /// Returns the number of values stored in the tree.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.insert(10);
        /// tree.insert(20);
        ///
        /// assert_eq!(tree.len(), 2);
        /// ```
        pub fn len(&self) -> usize {
            self.count
        }

        /// Returns `true` if the tree contains no values.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::<i32>::new();
        /// assert!(tree.is_empty());
        ///
        /// tree.insert(10);
        /// assert!(!tree.is_empty());
        /// ```
        pub fn is_empty(&self) -> bool {
            self.count == 0
        }

        /// Removes all values from the tree.
        ///
        /// After calling `clear`, the tree is empty and can be reused.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([1, 2, 3]);
        ///
        /// tree.clear();
        ///
        /// assert!(tree.is_empty());
        /// assert_eq!(tree.len(), 0);
        /// ```
        pub fn clear(&mut self) {
            unsafe {
                if let Some(fixed_head) = self.fixed_head {
                    let root = (*fixed_head.as_ptr()).left;

                    (*fixed_head.as_ptr()).left = None;

                    self.remove_tree(root);
                }

                debug_assert_eq!(self.count, 0);
            }
        }

        /// Returns the smallest value in the tree.
        ///
        /// Returns `None` if the tree is empty.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([8, 3, 10, 1]);
        ///
        /// assert_eq!(tree.first(), Some(&1));
        /// ```
        pub fn first(&self) -> Option<&T> {
            self.minimum()
        }

        /// Returns the largest value in the tree.
        ///
        /// Returns `None` if the tree is empty.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([8, 3, 10, 14]);
        ///
        /// assert_eq!(tree.last(), Some(&14));
        /// ```
        pub fn last(&self) -> Option<&T> {
            self.maximum()
        }

        fn minimum(&self) -> Option<&T> {
            unsafe {
                let root = self.get_root()?;
                let node = self.find_min(root);
                Some(&node.as_ref().value)
            }
        }

        fn maximum(&self) -> Option<&T> {
            unsafe {
                let root = self.get_root()?;
                let node = self.find_max(root);

                Some(&node.as_ref().value)
            }
        }

        /// Returns the height of the tree.
        ///
        /// An empty tree has height `0`.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// assert_eq!(tree.height(), 0);
        ///
        /// tree.insert(10);
        /// assert_eq!(tree.height(), 1);
        /// ```
        pub fn height(&self) -> usize {
            unsafe fn height_from<T>(node: Link<T>) -> usize {
                unsafe {
                    match node {
                        None => 0,

                        Some(node) => {
                            let left_height = height_from(node.as_ref().left);
                            let right_height = height_from(node.as_ref().right);

                            1 + left_height.max(right_height)
                        }
                    }
                }
            }

            unsafe { height_from(self.get_root()) }
        }

        /// Returns `true` if the tree contains `value`.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([1, 3, 5]);
        ///
        /// assert!(tree.contains(&3));
        /// assert!(!tree.contains(&4));
        /// ```
        pub fn contains(&self, value: &T) -> bool {
            !find_node(self.get_root(), value).is_none()
        }

        /// Inserts a value into the tree.
        ///
        /// Returns `true` if the value was inserted.
        ///
        /// Returns `false` if the value already exists.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        ///
        /// assert!(tree.insert(10));
        /// assert!(!tree.insert(10));
        /// ```
        pub fn insert(&mut self, value: T) -> bool {
            unsafe {
                if let Some(fixed_head) = self.fixed_head {
                    if (*fixed_head.as_ptr()).left.is_none() {
                        (*fixed_head.as_ptr()).left = Node::new_black(value);
                        self.count += 1;
                        return true;
                    }

                    let parent = self.find_put_parent_candidate(self.get_root(), &value);

                    if let Some(parent) = parent {
                        if self.attach_node(parent, value) {
                            self.put_balancing(parent);
                        } else {
                            return false;
                        }
                    } else {
                        return false;
                    }
                } else {
                    self.fixed_head = Node::new_fixed_head(value);
                }

                self.count += 1;
                true
            }
        }

        /// Removes a value from the tree.
        ///
        /// Returns `true` if the value existed and was removed.
        ///
        /// Use [`RedBlackTree::take`] when ownership of the removed value is needed.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.insert(10);
        ///
        /// assert!(tree.remove(&10));
        /// assert!(!tree.contains(&10));
        /// assert!(!tree.remove(&10));
        /// ```
        pub fn remove(&mut self, value: &T) -> bool {
            self.take(value).is_some()
        }

        /// Inserts `value` into the tree, replacing an existing equal value.
        ///
        /// If the tree already contains a value that compares equal to `value`,
        /// the existing value is replaced and returned.
        ///
        /// If no equal value exists, `value` is inserted and `None` is returned.
        ///
        /// This is especially useful for custom types whose [`Ord`] implementation
        /// compares only a key field.
        ///
        /// # Examples
        ///
        /// ```
        /// use std::cmp::Ordering;
        /// use rbtree_extended::RedBlackTree;
        ///
        /// #[derive(Debug, Default)]
        /// struct User {
        ///     id: u32,
        ///     name: String,
        /// }
        ///
        /// impl PartialEq for User {
        ///     fn eq(&self, other: &Self) -> bool {
        ///         self.id == other.id
        ///     }
        /// }
        ///
        /// impl Eq for User {}
        ///
        /// impl PartialOrd for User {
        ///     fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        ///         Some(self.cmp(other))
        ///     }
        /// }
        ///
        /// impl Ord for User {
        ///     fn cmp(&self, other: &Self) -> Ordering {
        ///         self.id.cmp(&other.id)
        ///     }
        /// }
        ///
        /// let mut users = RedBlackTree::new();
        ///
        /// users.insert(User {
        ///     id: 1,
        ///     name: "Alice".into(),
        /// });
        ///
        /// let old = users.replace(User {
        ///     id: 1,
        ///     name: "Bob".into(),
        /// });
        ///
        /// assert_eq!(old.unwrap().name, "Alice");
        /// assert_eq!(users.first().unwrap().name, "Bob");
        /// ```
        pub fn replace(&mut self, value: T) -> Option<T> {
            unsafe {
                if let Some(mut node) = find_node(self.get_root(), &value) {
                    return Some(std::mem::replace(&mut node.as_mut().value, value));
                }
            }

            self.insert(value);

            None
        }

        unsafe fn take_node(&mut self, mut node: NonNull<Node<T>>) -> Option<T> {
            unsafe {
                // Save the original value before the internal removal algorithm
                // starts swapping values between nodes.
                let removed_value = std::mem::take(&mut node.as_mut().value);

                if !self.remove_node(node) {
                    return None;
                }

                self.count -= 1;

                Some(removed_value)
            }
        }

        /// Removes and returns the value equal to `value`.
        ///
        /// Returns `None` if the value is not present in the tree.
        ///
        /// Unlike [`RedBlackTree::remove`], this method gives ownership of the
        /// removed value back to the caller.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([10, 5, 20]);
        ///
        /// assert_eq!(tree.take(&10), Some(10));
        /// assert!(!tree.contains(&10));
        /// assert_eq!(tree.take(&100), None);
        /// ```
        pub fn take(&mut self, value: &T) -> Option<T> {
            if self.is_empty() {
                return None;
            }

            unsafe {
                let node = find_node(self.get_root(), value)?;
                self.take_node(node)
            }
        }

        /// Retains only the values specified by the predicate.
        ///
        /// In other words, removes every value for which `f(&value)` returns `false`.
        ///
        /// The predicate receives a shared reference to each stored value.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([1, 2, 3, 4, 5, 6]);
        ///
        /// tree.retain(|value| value % 2 == 0);
        ///
        /// assert_eq!(
        ///     tree.iter().copied().collect::<Vec<_>>(),
        ///     vec![2, 4, 6]
        /// );
        /// ```
        ///
        /// Retaining no values empties the tree:
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([1, 2, 3]);
        ///
        /// tree.retain(|_| false);
        ///
        /// assert!(tree.is_empty());
        /// ```
        pub fn retain<F>(&mut self, mut f: F)
        where
            F: FnMut(&T) -> bool,
        {
            let mut retained = Self::new();

            while let Some(value) = self.pop_first() {
                if f(&value) {
                    retained.insert(value);
                }
            }

            *self = retained;
        }

        /// Removes and returns the smallest value in the tree.
        ///
        /// Returns `None` if the tree is empty.
        ///
        /// This operation is useful when values need to be processed in
        /// ascending order.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([8, 3, 10, 1, 6]);
        ///
        /// assert_eq!(tree.pop_first(), Some(1));
        /// assert_eq!(tree.pop_first(), Some(3));
        /// assert_eq!(tree.len(), 3);
        /// ```
        pub fn pop_first(&mut self) -> Option<T> {
            unsafe {
                let root = self.get_root()?;
                let node = self.find_min(root);

                self.take_node(node)
            }
        }

        /// Removes and returns the largest value in the tree.
        ///
        /// Returns `None` if the tree is empty.
        ///
        /// This operation can be used to implement a priority queue where the
        /// greatest value represents the highest priority.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([8, 3, 10, 1, 6]);
        ///
        /// assert_eq!(tree.pop_last(), Some(10));
        /// assert_eq!(tree.pop_last(), Some(8));
        /// assert_eq!(tree.len(), 3);
        /// ```
        pub fn pop_last(&mut self) -> Option<T> {
            unsafe {
                let root = self.get_root()?;
                let node = self.find_max(root);

                self.take_node(node)
            }
        }

        /// Returns a reference to the stored value equal to `value`.
        ///
        /// Returns `None` if no matching value exists.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([1, 3, 5]);
        ///
        /// assert_eq!(tree.get(&3), Some(&3));
        /// assert_eq!(tree.get(&4), None);
        /// ```
        pub fn get(&self, value: &T) -> Option<&T> {
            unsafe {
                let node = find_node(self.get_root(), value)?;
                Some(&node.as_ref().value)
            }
        }

        /// Returns the next greater value in sorted order.
        ///
        /// Returns `None` if `value` is not present or if it is the largest value.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([1, 3, 5, 7]);
        ///
        /// assert_eq!(tree.successor(&3), Some(&5));
        /// assert_eq!(tree.successor(&7), None);
        /// ```
        pub fn successor(&self, value: &T) -> Option<&T> {
            unsafe {
                let node = find_node(self.get_root(), value)?;

                // Case 1:
                // there is a right subtree - successor = minimum element on the right
                if let Some(right) = node.as_ref().right {
                    let successor = self.find_min(right);
                    return Some(&successor.as_ref().value);
                }

                // Case 2:
                // there is no right subtree
                // Move up while the current node is a right child
                let mut current = node;
                let mut parent = current.as_ref().parent;

                while let Some(p) = parent {
                    if let Some(left) = p.as_ref().left
                        && std::ptr::eq(left.as_ptr(), current.as_ptr())
                    {
                        return Some(&p.as_ref().value);
                    }

                    current = p;
                    parent = p.as_ref().parent;
                }

                None
            }
        }

        /// Returns the previous smaller value in sorted order.
        ///
        /// Returns `None` if `value` is not present or if it is the smallest value.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([1, 3, 5, 7]);
        ///
        /// assert_eq!(tree.predecessor(&5), Some(&3));
        /// assert_eq!(tree.predecessor(&1), None);
        /// ```
        pub fn predecessor(&self, value: &T) -> Option<&T> {
            unsafe {
                let node = find_node(self.get_root(), value)?;

                // Case 1:
                // there is a left subtree - predecessor = maximum element on the left
                if let Some(left) = node.as_ref().left {
                    let predecessor = self.find_max(left);
                    return Some(&predecessor.as_ref().value);
                }

                // Case 2:
                // there is no left subtree
                // Move up while the current node is a left child
                let mut current = node;
                let mut parent = current.as_ref().parent;

                while let Some(p) = parent {
                    if let Some(right) = p.as_ref().right
                        && std::ptr::eq(right.as_ptr(), current.as_ptr())
                    {
                        return Some(&p.as_ref().value);
                    }

                    current = p;
                    parent = p.as_ref().parent;
                }

                None
            }
        }

        /// Returns the first value greater than or equal to `value`.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([1, 3, 6, 8]);
        ///
        /// assert_eq!(tree.lower_bound(&5), Some(&6));
        /// assert_eq!(tree.lower_bound(&6), Some(&6));
        /// ```
        pub fn lower_bound(&self, value: &T) -> Option<&T> {
            unsafe {
                let mut current = self.get_root();
                let mut candidate: Link<T> = None;

                while let Some(node) = current {
                    match node.as_ref().value.cmp(value) {
                        Ordering::Less => {
                            current = node.as_ref().right;
                        }

                        Ordering::Equal => {
                            return Some(&node.as_ref().value);
                        }

                        Ordering::Greater => {
                            candidate = Some(node);
                            current = node.as_ref().left;
                        }
                    }
                }

                candidate.map(|node| &node.as_ref().value)
            }
        }

        /// Returns the first value strictly greater than `value`.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([1, 3, 6, 8]);
        ///
        /// assert_eq!(tree.upper_bound(&6), Some(&8));
        /// assert_eq!(tree.upper_bound(&8), None);
        /// ```
        pub fn upper_bound(&self, value: &T) -> Option<&T> {
            unsafe {
                let mut current = self.get_root();
                let mut candidate: Link<T> = None;

                while let Some(node) = current {
                    match node.as_ref().value.cmp(value) {
                        Ordering::Less | Ordering::Equal => {
                            current = node.as_ref().right;
                        }
                        Ordering::Greater => {
                            candidate = Some(node);
                            current = node.as_ref().left;
                        }
                    }
                }

                candidate.map(|node| &node.as_ref().value)
            }
        }

        /// Returns an iterator over values in the inclusive range `[min, max]`.
        ///
        /// Values are yielded in ascending order.
        ///
        /// The iterator is lazy: values are produced only as they are requested,
        /// rather than being collected into an intermediate `Vec`.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([1, 3, 5, 7, 9, 11]);
        ///
        /// let values: Vec<_> = tree
        ///     .range(&3, &9)
        ///     .copied()
        ///     .collect();
        ///
        /// assert_eq!(values, vec![3, 5, 7, 9]);
        /// ```
        pub fn range(&self, min: &T, max: &T) -> Range<'_, T> {
            Range::new(self.get_root(), min, max)
        }

        /// Returns the next value in an in-order (`LNR`) traversal.
        ///
        /// For a binary search tree, in-order traversal visits values in ascending order.
        ///
        /// Returns `None` if `value` is not present or has no successor in this traversal.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([4, 2, 6, 1, 3, 5, 7]);
        ///
        /// assert_eq!(tree.successor_dfs_in_order(4), Some(&5));
        /// ```
        pub fn successor_dfs_in_order(&self, value: T) -> Option<&T> {
            unsafe {
                let node = find_node(self.get_root(), &value);
                if let Some(n) = node
                    && let Some(nodesucc) = successor_of_node_in_order(n)
                {
                    return Some(&nodesucc.as_ref().value);
                }
                None
            }
        }

        /// Returns the next value in reverse in-order (`RNL`) traversal.
        ///
        /// For a binary search tree, reverse in-order traversal visits values in
        /// descending order.
        ///
        /// Returns `None` if `value` is not present or has no successor in this traversal.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([4, 2, 6, 1, 3, 5, 7]);
        ///
        /// assert_eq!(tree.successor_dfs_reverse_in_order(6), Some(&5));
        /// ```
        pub fn successor_dfs_reverse_in_order(&self, value: T) -> Option<&T> {
            unsafe {
                if let Some(node) = find_node(self.get_root(), &value)
                    && let Some(next) = successor_of_node_reverse_in_order(node)
                {
                    return Some(&next.as_ref().value);
                }
                None
            }
        }

        /// Returns the next value in post-order (`LRN`) traversal.
        ///
        /// Post-order visits the left subtree, then the right subtree,
        /// and finally the current node.
        ///
        /// Returns `None` if `value` is not present or has no successor in this traversal.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([4, 2, 6, 1, 3, 5, 7]);
        ///
        /// // Post-order: 1, 3, 2, 5, 7, 6, 4
        /// assert_eq!(tree.successor_dfs_post_order(3), Some(&2));
        /// assert_eq!(tree.successor_dfs_post_order(2), Some(&5));
        /// assert_eq!(tree.successor_dfs_post_order(4), None);
        /// ```
        pub fn successor_dfs_post_order(&self, value: T) -> Option<&T> {
            unsafe {
                if let Some(n) = find_node(self.get_root(), &value)
                    && let Some(nodesucc) = successor_of_node_post_order(n)
                {
                    return Some(&nodesucc.as_ref().value);
                }
                None
            }
        }

        /// Returns the next value in pre-order (`NLR`) traversal.
        ///
        /// Pre-order visits the current node first, followed by the left and right
        /// subtrees.
        ///
        /// Returns `None` if `value` is not present or has no successor in this traversal.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([4, 2, 6, 1, 3, 5, 7]);
        ///
        /// let first = *tree.iter_preorder().next().unwrap();
        /// assert_eq!(tree.successor_dfs_pre_order(first), tree.iter_preorder().nth(1));
        /// ```
        pub fn successor_dfs_pre_order(&self, value: T) -> Option<&T> {
            unsafe {
                if let Some(n) = find_node(self.get_root(), &value)
                    && let Some(nodesucc) = successor_of_node_pre_order(n)
                {
                    return Some(&nodesucc.as_ref().value);
                }
                None
            }
        }

        fn get_root(&self) -> Link<T> {
            if let Some(fixed_head) = self.fixed_head {
                unsafe { (*fixed_head.as_ptr()).left }
            } else {
                None
            }
        }

        unsafe fn operation_remove(&self, node_x: &NonNull<Node<T>>) -> OperationRemove {
            unsafe {
                if node_x.as_ref().is_red
                    && node_x.as_ref().left.is_none()
                    && node_x.as_ref().right.is_none()
                {
                    return OperationRemove::RedLeaf;
                }
                if node_x.as_ref().is_red
                    && node_x.as_ref().left.is_some()
                    && node_x.as_ref().right.is_some()
                {
                    return OperationRemove::NodeWithChildren;
                }
                if !node_x.as_ref().is_red {
                    if node_x.as_ref().left.is_some() && node_x.as_ref().right.is_some() {
                        return OperationRemove::NodeWithChildren;
                    } else if node_x.as_ref().left.is_some() && node_x.as_ref().right.is_none() {
                        if let Some(left) = node_x.as_ref().left
                            && left.as_ref().is_red
                            && left.as_ref().left.is_none()
                            && left.as_ref().right.is_none()
                        {
                            return OperationRemove::BlackNodeWithRedLeaf;
                        }
                    } else if node_x.as_ref().left.is_none() && node_x.as_ref().right.is_none() {
                        return OperationRemove::BlackLeaf;
                    }
                }
                panic!();
            }
        }

        unsafe fn operation_remove_black_leaf(
            &self,
            node_x: &NonNull<Node<T>>,
        ) -> OperationRemoveBlackLeaf {
            unsafe {
                if let Some(node_a) = node_x.as_ref().parent {
                    if node_a.as_ref().is_red {
                        if let Some(node_b) = node_a.as_ref().left
                            && !std::ptr::eq(node_b.as_ptr(), node_x.as_ptr())
                            && !node_b.as_ref().is_red
                        {
                            if let Some(node_c) = node_b.as_ref().left
                                && node_c.as_ref().is_red
                            {
                                return OperationRemoveBlackLeaf::LeftRedABlackBRedCleaf;
                                // 2.1.1.1
                            }

                            // sibling B is black and its left child is either absent or also black
                            return OperationRemoveBlackLeaf::LeftRedABlackBleaf;
                            // 2.1.2.1
                        }

                        if let Some(node_b) = node_a.as_ref().right
                            && !std::ptr::eq(node_b.as_ptr(), node_x.as_ptr())
                            && !node_b.as_ref().is_red
                        {
                            if let Some(node_c) = node_b.as_ref().left
                                && node_c.as_ref().is_red
                            {
                                return OperationRemoveBlackLeaf::RightRedABlackBRedCleaf;
                                // 2.1.1.2
                            }

                            // sibling B is black and its left child is either absent or also black
                            return OperationRemoveBlackLeaf::RightRedABlackBleaf;
                            // 2.1.2.2
                        }
                    } else {
                        if let Some(node_b) = node_a.as_ref().left
                            && !std::ptr::eq(node_b.as_ptr(), node_x.as_ptr())
                        {
                            if node_b.as_ref().is_red && node_b.as_ref().right.is_some() {
                                let node_c = node_b.as_ref().right.unwrap();
                                if !node_c.as_ref().is_red {
                                    if node_c.as_ref().left.is_some()
                                        && let Some(node_d) = node_c.as_ref().left
                                        && node_d.as_ref().is_red
                                    {
                                        return OperationRemoveBlackLeaf::BlackARedBWithBlackChildrenRightHaveRedLeaf;
                                        // 2.2.1
                                    }
                                    return OperationRemoveBlackLeaf::BlackARedBWithBlackChildrenLeaf;
                                    // 2.2.2
                                }
                            }
                            if !node_b.as_ref().is_red
                                && node_b.as_ref().left.is_some()
                                && let Some(node_d) = node_b.as_ref().left
                                && node_d.as_ref().is_red
                            {
                                return OperationRemoveBlackLeaf::BlackALeftBlackBRedDleaf;
                                // 2.3.1.1
                            }
                            if !node_b.as_ref().is_red {
                                return OperationRemoveBlackLeaf::BlackALeftBlackBleaf;
                                // 2.3.2.1
                            }
                        }
                        if let Some(node_b) = node_a.as_ref().right
                            && !std::ptr::eq(node_b.as_ptr(), node_x.as_ptr())
                        {
                            if !node_b.as_ref().is_red
                                && node_b.as_ref().left.is_some()
                                && let Some(node_d) = node_b.as_ref().left
                                && node_d.as_ref().is_red
                            {
                                return OperationRemoveBlackLeaf::BlackARightBlackBRedDleaf;
                                // 2.3.1.2
                            }
                            if !node_b.as_ref().is_red {
                                return OperationRemoveBlackLeaf::BlackARightBlackBleaf;
                                // 2.3.2.2
                            }
                        }
                    }
                } else {
                    return OperationRemoveBlackLeaf::Root;
                }
                OperationRemoveBlackLeaf::Unimplemented
            }
        }

        unsafe fn remove_black_leaf(&mut self, node_x: NonNull<Node<T>>) -> bool {
            unsafe {
                let mut next = node_x;
                let mut removed = false;
                loop {
                    match self.operation_remove_black_leaf(&next) {
                        OperationRemoveBlackLeaf::LeftRedABlackBRedCleaf => {
                            self.remove_black_leaf_2_1_1_1_balancing(&next);
                            if !removed {
                                removed = self.remove_leaf(node_x);
                            }
                            break;
                        }
                        OperationRemoveBlackLeaf::RightRedABlackBRedCleaf => {
                            self.remove_black_leaf_2_1_1_2_balancing(&next);
                            if !removed {
                                removed = self.remove_leaf(node_x);
                            }
                            break;
                        }
                        OperationRemoveBlackLeaf::LeftRedABlackBleaf => {
                            self.remove_black_leaf_2_1_2_1_balancing(&next);
                            if !removed {
                                removed = self.remove_leaf(node_x);
                            }
                            break;
                        }
                        OperationRemoveBlackLeaf::RightRedABlackBleaf => {
                            self.remove_black_leaf_2_1_2_2_balancing(&next);
                            if !removed {
                                removed = self.remove_leaf(node_x);
                            }
                            break;
                        }
                        OperationRemoveBlackLeaf::BlackARedBWithBlackChildrenRightHaveRedLeaf => {
                            self.remove_black_leaf_2_2_1_balancing(&next);
                            if !removed {
                                removed = self.remove_leaf(node_x);
                            }
                            break;
                        }
                        OperationRemoveBlackLeaf::BlackARedBWithBlackChildrenLeaf => {
                            self.remove_black_leaf_2_2_2_balancing(&next);
                            if !removed {
                                removed = self.remove_leaf(node_x);
                            }
                            break;
                        }
                        OperationRemoveBlackLeaf::BlackALeftBlackBRedDleaf => {
                            self.remove_black_leaf_2_3_1_1_balancing(&next);
                            if !removed {
                                removed = self.remove_leaf(node_x);
                            }
                            break;
                        }
                        OperationRemoveBlackLeaf::BlackARightBlackBRedDleaf => {
                            self.remove_black_leaf_2_3_1_2_balancing(&next);
                            if !removed {
                                removed = self.remove_leaf(node_x);
                            }
                            break;
                        }
                        OperationRemoveBlackLeaf::BlackALeftBlackBleaf => {
                            next = self.remove_black_leaf_2_3_2_1_balancing(&next);
                            if !removed {
                                removed = self.remove_leaf(node_x);
                            }
                        }
                        OperationRemoveBlackLeaf::BlackARightBlackBleaf => {
                            next = self.remove_black_leaf_2_3_2_2_balancing(&next);
                            if !removed {
                                removed = self.remove_leaf(node_x);
                            }
                        }
                        OperationRemoveBlackLeaf::Root => {
                            if !removed {
                                // We get here when the node_x being deleted is root
                                if let Some(fixed_head) = self.fixed_head {
                                    (*fixed_head.as_ptr()).left = None;
                                }
                                let _ = Box::from_raw(node_x.as_ptr());
                                removed = true;
                            }
                            break;
                        }
                        OperationRemoveBlackLeaf::Unimplemented => {
                            panic!("unimplemented black leaf removal case");
                        }
                    }
                }
                removed
            }
        }

        /// 2.1.1.1 remove black X
        ///
        /// ```text
        ///             P            P
        ///            //           //
        ///            A            B
        ///           / \          / \
        ///          B   X   =>   C   A
        ///         //\              /
        ///        C   D            D
        /// ```
        unsafe fn remove_black_leaf_2_1_1_1_balancing(&mut self, node_x: &NonNull<Node<T>>) {
            unsafe {
                let node_a = (*node_x.as_ptr()).parent.unwrap();
                let node_b = (*node_a.as_ptr()).left.unwrap();
                let node_d = (*node_b.as_ptr()).right;
                (*node_b.as_ptr()).parent = (*node_a.as_ptr()).parent;
                if let Some(ref mut parent) = (*node_b.as_ptr()).parent {
                    (*parent.as_ptr()).left = Some(node_b);
                }
                (*node_a.as_ptr()).left = node_d;
                if let Some(n_d) = node_d {
                    (*n_d.as_ptr()).parent = Some(node_a);
                }
                (*node_a.as_ptr()).is_red = false;
                (*node_b.as_ptr()).right = Some(node_a);
                (*node_a.as_ptr()).parent = Some(node_b);
                (*node_b.as_ptr()).is_red = true;
                if let Some(node_c) = (*node_b.as_ptr()).left {
                    (*node_c.as_ptr()).is_red = false;
                }
            }
        }

        /// 2.1.1.2 remove black X
        ///
        /// ```text
        ///             P              P
        ///            //             //
        ///           A               C
        ///          / \            /   \
        ///         X   B   =>     A     B
        ///            //           \   /
        ///            C             E D
        ///           / \
        ///          E   D
        /// ```
        unsafe fn remove_black_leaf_2_1_1_2_balancing(&mut self, node_x: &NonNull<Node<T>>) {
            unsafe {
                let node_a = (*node_x.as_ptr()).parent.unwrap();
                (*node_a.as_ptr()).is_red = false;
                let parent: NonNull<Node<T>> = (*node_a.as_ptr()).parent.unwrap();
                let node_b = (*node_a.as_ptr()).right.unwrap();
                let node_c = (*node_b.as_ptr()).left.unwrap();
                let node_e = (*node_c.as_ptr()).left;
                let node_d = (*node_c.as_ptr()).right;
                (*parent.as_ptr()).left = Some(node_c);
                (*node_c.as_ptr()).parent = Some(parent);
                (*node_b.as_ptr()).left = node_d;
                if let Some(n_d) = node_d {
                    (*n_d.as_ptr()).parent = Some(node_b);
                }
                (*node_c.as_ptr()).right = Some(node_b);
                (*node_b.as_ptr()).parent = Some(node_c);
                (*node_c.as_ptr()).left = Some(node_a);
                (*node_a.as_ptr()).parent = Some(node_c);
                (*node_a.as_ptr()).right = node_e;
                if let Some(n_e) = node_e {
                    (*n_e.as_ptr()).parent = Some(node_a);
                }
            }
        }

        /// 2.1.2.1 remove black X
        ///
        /// ```text
        ///              P            P
        ///             //           /
        ///            A            A
        ///           / \          //
        ///          B   X   =>   B
        ///
        /// ```
        unsafe fn remove_black_leaf_2_1_2_1_balancing(&mut self, node_x: &NonNull<Node<T>>) {
            unsafe {
                let node_a = (*node_x.as_ptr()).parent.unwrap();
                (*node_a.as_ptr()).is_red = false;
                if let Some(node_b) = (*node_a.as_ptr()).left {
                    (*node_b.as_ptr()).is_red = true;
                }
            }
        }

        /// 2.1.2.2 remove black X
        ///
        /// ```text
        ///             P            P
        ///            //           /
        ///            A     =>     B
        ///           / \          //\
        ///          X   B        A   D
        ///             / \        \
        ///            C   D        C
        /// ```
        unsafe fn remove_black_leaf_2_1_2_2_balancing(&mut self, node_x: &NonNull<Node<T>>) {
            unsafe {
                let node_a = (*node_x.as_ptr()).parent.unwrap();
                let node_b = (*node_a.as_ptr()).right.unwrap();
                let node_c = (*node_b.as_ptr()).left;
                let node_d = (*node_b.as_ptr()).right;
                let parent = (*node_a.as_ptr()).parent.unwrap();
                if let Some(left) = (*parent.as_ptr()).left {
                    if std::ptr::eq(node_a.as_ptr(), left.as_ptr()) {
                        (*parent.as_ptr()).left = Some(node_b);
                    } else {
                        (*parent.as_ptr()).right = Some(node_b);
                    }
                } else {
                    (*parent.as_ptr()).right = Some(node_b);
                }
                (*node_b.as_ptr()).parent = Some(parent);
                (*node_b.as_ptr()).left = Some(node_a);
                (*node_b.as_ptr()).right = node_d;
                if let Some(n_d) = node_d {
                    (*n_d.as_ptr()).parent = Some(node_b);
                }
                (*node_a.as_ptr()).parent = Some(node_b);
                (*node_a.as_ptr()).right = node_c;
                if let Some(n_c) = node_c {
                    (*n_c.as_ptr()).parent = Some(node_a);
                }
            }
        }

        /// 2.2.1 remove black X
        ///
        /// ```text
        ///            A               C
        ///          // \            //  \
        ///         B    X    =>    B     A
        ///          \               \   /
        ///           C               D E
        ///           //\
        ///          D   E
        /// ```
        unsafe fn remove_black_leaf_2_2_1_balancing(&mut self, node_x: &NonNull<Node<T>>) {
            unsafe {
                let n_a = node_x.as_ref().parent.unwrap();
                if n_a.as_ref().parent.is_some() {
                    let parent = (*n_a.as_ptr()).parent.unwrap();
                    let mut node_a_from_left = false;
                    if let Some(ref mut node_a) = (*parent.as_ptr()).left
                        && std::ptr::eq(node_a.as_ptr(), n_a.as_ptr())
                    {
                        node_a_from_left = true;
                    }
                    let node_a = if node_a_from_left {
                        (*parent.as_ptr()).left.unwrap()
                    } else {
                        (*parent.as_ptr()).right.unwrap()
                    };
                    let node_b = (*node_a.as_ptr()).left.unwrap();
                    let node_c = (*node_b.as_ptr()).right.unwrap();
                    let node_e = (*node_c.as_ptr()).right;
                    let node_d = (*node_c.as_ptr()).left.unwrap();
                    (*node_b.as_ptr()).right = Some(node_d);
                    (*node_b.as_ptr()).parent = Some(node_c);
                    (*node_d.as_ptr()).parent = Some(node_b);
                    (*node_a.as_ptr()).parent = Some(node_c);
                    (*node_a.as_ptr()).left = node_e;
                    if let Some(n_e) = node_e {
                        (*n_e.as_ptr()).parent = Some(node_a);
                    }
                    (*node_d.as_ptr()).is_red = false;
                    (*node_c.as_ptr()).left = Some(node_b);
                    (*node_c.as_ptr()).right = Some(node_a);
                    (*node_c.as_ptr()).parent = Some(parent);
                    if node_a_from_left {
                        (*parent.as_ptr()).left = Some(node_c);
                    } else {
                        (*parent.as_ptr()).right = Some(node_c);
                    }
                } else {
                    // node_a is root
                    if let Some(fixed_head) = self.fixed_head {
                        let node_a = (*fixed_head.as_ptr()).left.unwrap();
                        let node_b = (*node_a.as_ptr()).left.unwrap();
                        let node_c = (*node_b.as_ptr()).right.unwrap();
                        let node_e = (*node_c.as_ptr()).right;
                        let node_d = (*node_c.as_ptr()).left.unwrap();
                        (*node_b.as_ptr()).right = Some(node_d);
                        (*node_b.as_ptr()).parent = Some(node_c);
                        (*node_d.as_ptr()).parent = Some(node_b);
                        (*node_a.as_ptr()).parent = Some(node_c);
                        (*node_a.as_ptr()).left = node_e;
                        if let Some(n_e) = node_e {
                            (*n_e.as_ptr()).parent = Some(node_a);
                        }
                        (*node_d.as_ptr()).is_red = false;
                        (*node_c.as_ptr()).left = Some(node_b);
                        (*node_c.as_ptr()).right = Some(node_a);
                        (*node_c.as_ptr()).parent = None;
                        (*fixed_head.as_ptr()).left = Some(node_c);
                    }
                }
            }
        }

        /// 2.2.2 remove black X
        ///
        /// ```text
        ///    A            B
        ///  // \            \
        ///  B    X   =>       A
        ///  \               //
        ///   C             C
        /// ```
        unsafe fn remove_black_leaf_2_2_2_balancing(&mut self, node_x: &NonNull<Node<T>>) {
            unsafe {
                let n_a = node_x.as_ref().parent.unwrap();
                if n_a.as_ref().parent.is_some() {
                    let parent = (*n_a.as_ptr()).parent.unwrap();
                    let mut node_a_from_left = false;
                    if let Some(ref mut node_a) = (*parent.as_ptr()).left
                        && std::ptr::eq(node_a.as_ptr(), n_a.as_ptr())
                    {
                        node_a_from_left = true;
                    }
                    let node_a = if node_a_from_left {
                        (*parent.as_ptr()).left.unwrap()
                    } else {
                        (*parent.as_ptr()).right.unwrap()
                    };
                    let node_b = (*node_a.as_ptr()).left.unwrap();
                    (*node_b.as_ptr()).is_red = false;
                    (*node_b.as_ptr()).parent = Some(parent);
                    let node_c = (*node_b.as_ptr()).right.unwrap();
                    (*node_c.as_ptr()).is_red = true;
                    (*node_b.as_ptr()).right = Some(node_a);
                    (*node_a.as_ptr()).left = Some(node_c);
                    (*node_c.as_ptr()).parent = Some(node_a);
                    (*node_a.as_ptr()).parent = Some(node_b);
                    if node_a_from_left {
                        (*parent.as_ptr()).left = Some(node_b);
                    } else {
                        (*parent.as_ptr()).right = Some(node_b);
                    }
                } else {
                    // node_a is root
                    if let Some(fixed_head) = self.fixed_head {
                        let node_a = (*fixed_head.as_ptr()).left.unwrap();
                        let node_b = (*node_a.as_ptr()).left.unwrap();
                        (*node_b.as_ptr()).is_red = false;
                        (*node_b.as_ptr()).parent = None;
                        let node_c = (*node_b.as_ptr()).right.unwrap();
                        (*node_c.as_ptr()).is_red = true;
                        (*node_b.as_ptr()).right = Some(node_a);
                        (*node_a.as_ptr()).left = Some(node_c);
                        (*node_c.as_ptr()).parent = Some(node_a);
                        (*node_a.as_ptr()).parent = Some(node_b);
                        (*fixed_head.as_ptr()).left = Some(node_b);
                    }
                }
            }
        }

        /// 2.3.1.1 remove black X
        ///
        /// ```text
        ///      A           B
        ///     / \         / \
        ///    B   X  =>   D   A
        ///   // \            /
        ///  D    C          C
        /// ```
        unsafe fn remove_black_leaf_2_3_1_1_balancing(&mut self, node_x: &NonNull<Node<T>>) {
            unsafe {
                let node_a = (*node_x.as_ptr()).parent.unwrap();
                if let Some(parent) = (*node_a.as_ptr()).parent {
                    let node_b = (*node_a.as_ptr()).left.unwrap();
                    let node_c = (*node_b.as_ptr()).right;
                    let node_d = (*node_b.as_ptr()).left.unwrap();
                    (*node_d.as_ptr()).is_red = false;
                    let mut node_a_from_left = false;
                    if let Some(p_node_a) = (*parent.as_ptr()).left
                        && std::ptr::eq(p_node_a.as_ptr(), node_a.as_ptr())
                    {
                        node_a_from_left = true;
                    }
                    (*node_b.as_ptr()).parent = Some(parent);
                    (*node_b.as_ptr()).right = Some(node_a);
                    (*node_a.as_ptr()).parent = Some(node_b);
                    (*node_a.as_ptr()).left = node_c;
                    if let Some(n_c) = node_c {
                        (*n_c.as_ptr()).parent = Some(node_a);
                    }
                    if node_a_from_left {
                        (*parent.as_ptr()).left = Some(node_b);
                    } else {
                        (*parent.as_ptr()).right = Some(node_b);
                    }
                } else {
                    // node_a is root
                    if let Some(fixed_head) = self.fixed_head {
                        let node_a = (*fixed_head.as_ptr()).left.unwrap();
                        let node_b = (*node_a.as_ptr()).left.unwrap();
                        let node_c = (*node_b.as_ptr()).right;
                        let node_d = (*node_b.as_ptr()).left.unwrap();
                        (*node_d.as_ptr()).is_red = false;
                        let node_b = (*node_a.as_ptr()).left.unwrap();
                        (*node_b.as_ptr()).parent = None;
                        (*node_b.as_ptr()).right = Some(node_a);
                        (*node_a.as_ptr()).parent = Some(node_b);
                        (*node_a.as_ptr()).left = node_c;
                        if let Some(n_c) = node_c {
                            (*n_c.as_ptr()).parent = Some(node_a);
                        }
                        (*fixed_head.as_ptr()).left = Some(node_b);
                    }
                }
            }
        }

        /// 2.3.1.2 remove black X
        ///
        /// ```text
        ///
        ///      A            D
        ///     / \         /   \
        ///    X   B  =>   A     B
        ///       //        \   /
        ///       D          C E
        ///      / \
        ///     C   E
        /// ```
        unsafe fn remove_black_leaf_2_3_1_2_balancing(&mut self, node_x: &NonNull<Node<T>>) {
            unsafe {
                let node_a = (*node_x.as_ptr()).parent.unwrap();
                if let Some(parent) = (*node_a.as_ptr()).parent {
                    let node_b = (*node_a.as_ptr()).right.unwrap();
                    let node_d = (*node_b.as_ptr()).left.unwrap();
                    let node_c = (*node_d.as_ptr()).left;
                    let node_e = (*node_d.as_ptr()).right;
                    (*node_d.as_ptr()).is_red = false;
                    let mut node_a_from_left = false;
                    if let Some(p_node_a) = (*parent.as_ptr()).left
                        && std::ptr::eq(p_node_a.as_ptr(), node_a.as_ptr())
                    {
                        node_a_from_left = true;
                    }
                    (*node_d.as_ptr()).parent = Some(parent);
                    (*node_d.as_ptr()).left = Some(node_a);
                    (*node_d.as_ptr()).right = Some(node_b);
                    (*node_a.as_ptr()).parent = Some(node_d);
                    (*node_b.as_ptr()).parent = Some(node_d);
                    (*node_a.as_ptr()).right = node_c;
                    if let Some(n_c) = node_c {
                        (*n_c.as_ptr()).parent = Some(node_a);
                    }
                    (*node_b.as_ptr()).left = node_e;
                    if let Some(n_e) = node_e {
                        (*n_e.as_ptr()).parent = Some(node_b);
                    }
                    if node_a_from_left {
                        (*parent.as_ptr()).left = Some(node_d);
                    } else {
                        (*parent.as_ptr()).right = Some(node_d);
                    }
                } else {
                    // node_a is root
                    if let Some(fixed_head) = self.fixed_head {
                        let node_a = (*fixed_head.as_ptr()).left.unwrap();
                        let node_b = (*node_a.as_ptr()).right.unwrap();
                        let node_d = (*node_b.as_ptr()).left.unwrap();
                        let node_c = (*node_d.as_ptr()).left;
                        let node_e = (*node_d.as_ptr()).right;
                        (*node_d.as_ptr()).is_red = false;
                        (*node_d.as_ptr()).parent = None;
                        (*node_d.as_ptr()).left = Some(node_a);
                        (*node_d.as_ptr()).right = Some(node_b);
                        (*node_a.as_ptr()).parent = Some(node_d);
                        (*node_b.as_ptr()).parent = Some(node_d);
                        (*node_a.as_ptr()).right = node_c;
                        if let Some(n_c) = node_c {
                            (*n_c.as_ptr()).parent = Some(node_a);
                        }
                        (*node_b.as_ptr()).left = node_e;
                        if let Some(n_e) = node_e {
                            (*n_e.as_ptr()).parent = Some(node_b);
                        }
                        (*fixed_head.as_ptr()).left = Some(node_d);
                    }
                }
            }
        }

        /// 2.3.2.1 remove black X
        ///
        /// ```text
        ///            P           P
        ///            |           |
        ///            A           A
        ///           / \   =>    //   => next check node A
        ///          B   X       B
        ///
        /// ```
        unsafe fn remove_black_leaf_2_3_2_1_balancing(
            &mut self,
            node_x: &NonNull<Node<T>>,
        ) -> NonNull<Node<T>> {
            unsafe {
                let node_a = (*node_x.as_ptr()).parent.unwrap();
                let node_b = (*node_a.as_ptr()).left.unwrap();
                (*node_b.as_ptr()).is_red = true;
                node_a
            }
        }

        /// 2.3.2.2 remove black X
        ///
        /// ```text
        ///              A            B
        ///             / \   =>    // \    =>  next check node B
        ///            X   B       A    D
        ///               / \       \
        ///              C   D       C
        /// ```
        unsafe fn remove_black_leaf_2_3_2_2_balancing(
            &mut self,
            node_x: &NonNull<Node<T>>,
        ) -> NonNull<Node<T>> {
            unsafe {
                let node_a = (*node_x.as_ptr()).parent.unwrap();
                (*node_a.as_ptr()).is_red = true;
                if let Some(parent) = (*node_a.as_ptr()).parent {
                    let node_b = (*node_a.as_ptr()).right.unwrap();
                    let node_c = (*node_b.as_ptr()).left;
                    let node_d = (*node_b.as_ptr()).right;
                    let mut node_a_from_left = false;
                    if let Some(p_node_a) = (*parent.as_ptr()).left
                        && std::ptr::eq(p_node_a.as_ptr(), node_a.as_ptr())
                    {
                        node_a_from_left = true;
                    }
                    (*node_b.as_ptr()).parent = Some(parent);
                    (*node_a.as_ptr()).right = node_c;
                    if let Some(n_c) = node_c {
                        (*n_c.as_ptr()).parent = Some(node_a);
                    }
                    (*node_b.as_ptr()).right = node_d;
                    if let Some(n_d) = node_d {
                        (*n_d.as_ptr()).parent = Some(node_b);
                    }
                    (*node_b.as_ptr()).left = Some(node_a);
                    (*node_a.as_ptr()).parent = Some(node_b);
                    if node_a_from_left {
                        (*parent.as_ptr()).left = Some(node_b);
                    } else {
                        (*parent.as_ptr()).right = Some(node_b);
                    }
                    node_b
                } else {
                    // node_a is root
                    if let Some(fixed_head) = self.fixed_head {
                        let node_a = (*fixed_head.as_ptr()).left.unwrap();
                        (*node_a.as_ptr()).is_red = true;
                        let node_b = (*node_a.as_ptr()).right.unwrap();
                        let node_c = (*node_b.as_ptr()).left;
                        let node_d = (*node_b.as_ptr()).right;
                        (*node_b.as_ptr()).parent = None;
                        (*node_a.as_ptr()).right = node_c;
                        if let Some(n_c) = node_c {
                            (*n_c.as_ptr()).parent = Some(node_a);
                        }
                        (*node_b.as_ptr()).right = node_d;
                        if let Some(n_d) = node_d {
                            (*n_d.as_ptr()).parent = Some(node_b);
                        }
                        (*node_b.as_ptr()).left = Some(node_a);
                        (*node_a.as_ptr()).parent = Some(node_b);
                        (*fixed_head.as_ptr()).left = Some(node_b);
                    }
                    self.get_root().unwrap()
                }
            }
        }

        unsafe fn remove_node(&mut self, node: NonNull<Node<T>>) -> bool {
            unsafe {
                match self.operation_remove(&node) {
                    OperationRemove::RedLeaf => {
                        // option 1.0.0
                        //
                        // ```text
                        //
                        //  P
                        //  ||
                        //  X
                        //
                        // ```

                        self.remove_leaf(node)
                    }
                    OperationRemove::BlackLeaf => {
                        // option 2 black leaf
                        self.remove_black_leaf(node)
                    }
                    OperationRemove::NodeWithChildren => {
                        // option 4.0.0
                        // ```text
                        //        X
                        //     /      \
                        //    L        R
                        //   / \      / \
                        // ...  C    L
                        //          /
                        //         C
                        //        ...
                        //
                        // ```
                        /*
                            The node has two children.

                            We take the predecessor:
                            the maximal node of the left subtree.

                            We only change the values,
                            then we delete the predecessor as a regular node.
                        */

                        let predecessor = self.find_max(node.as_ref().left.unwrap());

                        std::mem::swap(
                            &mut (*node.as_ptr()).value,
                            &mut (*predecessor.as_ptr()).value,
                        );

                        self.remove_node(predecessor)
                    }
                    OperationRemove::BlackNodeWithRedLeaf => {
                        // option 3.0.0
                        // ```text
                        //  X
                        // //
                        // A
                        // ```
                        let red_left = (*node.as_ptr()).left.unwrap();
                        std::mem::swap(&mut (*node.as_ptr()).value, &mut (*red_left.as_ptr()).value);
                        self.remove_leaf(red_left)
                    }
                }
            }
        }

        unsafe fn find_max(&self, node: NonNull<Node<T>>) -> NonNull<Node<T>> {
            unsafe {
                if node.as_ref().right.is_some() {
                    self.find_max(node.as_ref().right.unwrap())
                } else {
                    node
                }
            }
        }

        unsafe fn find_min(&self, node: NonNull<Node<T>>) -> NonNull<Node<T>> {
            unsafe {
                if node.as_ref().left.is_some() {
                    self.find_min(node.as_ref().left.unwrap())
                } else {
                    node
                }
            }
        }

        unsafe fn remove_leaf(&mut self, node: NonNull<Node<T>>) -> bool {
            unsafe {
                if let Some(mut parent) = node.as_ref().parent {
                    if let Some(ref mut left) = parent.as_mut().left {
                        if std::ptr::eq(left.as_ptr(), node.as_ptr()) {
                            parent.as_mut().left = None;
                        } else {
                            parent.as_mut().right = None;
                        }
                    } else {
                        parent.as_mut().right = None;
                    }
                }
                let _ = Box::from_raw(node.as_ptr());
                true
            }
        }

        unsafe fn remove_tree(&mut self, node: Link<T>) {
            unsafe {
                if let Some(node) = node {
                    self.remove_tree(node.as_ref().left);
                    self.remove_tree(node.as_ref().right);
                    if self.remove_leaf(node) {
                        assert!(self.count > 0);
                        self.count -= 1;
                    }
                }
            }
        }

        /// Rotate left and Rotate right and Flip color
        ///
        /// ```text
        ///             |              ||
        ///             P              C
        ///           //  \          /   \
        ///          A     F        A     P
        ///         / \\      =>   / \   / \
        ///        B   C          B   E D   F
        ///            / \
        ///           E   D
        /// ```
        unsafe fn rotate_left_right_flip_color(&mut self, node_a: NonNull<Node<T>>) -> Link<T> {
            unsafe {
                let node_p = (*node_a.as_ptr()).parent.unwrap();
                if let Some(parent) = (*node_p.as_ptr()).parent {
                    let mut node_p_from_left = false;
                    if let Some(p_node_p) = (*parent.as_ptr()).left
                        && std::ptr::eq(p_node_p.as_ptr(), node_p.as_ptr())
                    {
                        node_p_from_left = true;
                    }
                    let node_p = if node_p_from_left {
                        (*parent.as_ptr()).left.unwrap()
                    } else {
                        (*parent.as_ptr()).right.unwrap()
                    };
                    (*node_a.as_ptr()).is_red = false;
                    let node_c = (*node_a.as_ptr()).right.unwrap();
                    (*node_c.as_ptr()).is_red = false;
                    let node_e = (*node_c.as_ptr()).left;
                    let node_d = (*node_c.as_ptr()).right;
                    (*node_c.as_ptr()).is_red = true;
                    (*node_c.as_ptr()).parent = Some(parent);
                    (*node_c.as_ptr()).left = Some(node_a);
                    (*node_a.as_ptr()).parent = Some(node_c);
                    (*node_c.as_ptr()).right = Some(node_p);
                    (*node_p.as_ptr()).parent = Some(node_c);
                    (*node_p.as_ptr()).left = node_d;
                    if let Some(n_d) = node_d {
                        (*n_d.as_ptr()).parent = Some(node_p);
                    }
                    (*node_a.as_ptr()).right = node_e;
                    if let Some(n_e) = node_e {
                        (*n_e.as_ptr()).parent = Some(node_a);
                    }
                    if node_p_from_left {
                        (*parent.as_ptr()).left = Some(node_c);
                    } else {
                        (*parent.as_ptr()).right = Some(node_c);
                    }
                    Some(parent)
                } else {
                    let fixed_head = self.fixed_head.unwrap();
                    let node_p = (*fixed_head.as_ptr()).left.unwrap();

                    let node_a = (*node_p.as_ptr()).left.unwrap();
                    (*node_a.as_ptr()).is_red = false;
                    let node_c = (*node_a.as_ptr()).right.unwrap();
                    (*node_c.as_ptr()).is_red = false;
                    let node_e = (*node_c.as_ptr()).left;
                    let node_d = (*node_c.as_ptr()).right;
                    (*node_c.as_ptr()).is_red = false;
                    (*node_c.as_ptr()).parent = None;
                    (*node_c.as_ptr()).left = Some(node_a);
                    (*node_a.as_ptr()).parent = Some(node_c);
                    (*node_c.as_ptr()).right = Some(node_p);
                    (*node_p.as_ptr()).parent = Some(node_c);
                    (*node_p.as_ptr()).left = node_d;
                    if let Some(n_d) = node_d {
                        (*n_d.as_ptr()).parent = Some(node_p);
                    }
                    (*node_a.as_ptr()).right = node_e;
                    if let Some(n_e) = node_e {
                        (*n_e.as_ptr()).parent = Some(node_a);
                    }
                    (*fixed_head.as_ptr()).left = Some(node_c);
                    (*fixed_head.as_ptr()).left
                }
            }
        }

        /// Rotate left without parent
        /// A is root
        ///
        /// ```text
        ///             A                  C
        ///            / \\               //\
        ///           B    C     =>      A   D
        ///               / \           / \
        ///              E   D         B   E
        ///
        /// ```
        ///
        /// Rotate left  with parent
        ///
        /// ```text
        ///             P                  P
        ///             |                  |
        ///             A                  C
        ///            / \\               //\
        ///           B    C     =>      A   D
        ///               / \           / \
        ///              E   D         B   E
        ///
        /// ```
        unsafe fn rotate_left(&mut self, node_a: NonNull<Node<T>>) -> Link<T> {
            unsafe {
                if let Some(parent) = (*node_a.as_ptr()).parent {
                    let mut node_a_from_left = false;
                    if let Some(p_node_a) = (*parent.as_ptr()).left
                        && std::ptr::eq(p_node_a.as_ptr(), node_a.as_ptr())
                    {
                        node_a_from_left = true;
                    }
                    let node_a = if node_a_from_left {
                        (*parent.as_ptr()).left.unwrap()
                    } else {
                        (*parent.as_ptr()).right.unwrap()
                    };
                    let node_c = (*node_a.as_ptr()).right.unwrap();
                    (*node_c.as_ptr()).is_red = (*node_a.as_ptr()).is_red;
                    (*node_a.as_ptr()).is_red = true;
                    (*node_c.as_ptr()).parent = Some(parent);
                    if node_c.as_ref().left.is_some() {
                        let mut node_e = (*node_c.as_ptr()).left;
                        if let Some(e) = &mut node_e {
                            (*e.as_ptr()).parent = Some(node_a);
                        }
                        (*node_a.as_ptr()).right = node_e;
                    } else {
                        (*node_a.as_ptr()).right = None;
                    }
                    (*node_c.as_ptr()).left = Some(node_a);
                    (*node_a.as_ptr()).parent = Some(node_c);
                    if node_a_from_left {
                        (*parent.as_ptr()).left = Some(node_c);
                        (*parent.as_ptr()).left
                    } else {
                        (*parent.as_ptr()).right = Some(node_c);
                        (*parent.as_ptr()).right
                    }
                } else {
                    let fixed_head = self.fixed_head.unwrap();
                    let node_a = (*fixed_head.as_ptr()).left.unwrap();
                    let node_c = (*node_a.as_ptr()).right.unwrap();
                    (*node_c.as_ptr()).is_red = (*node_a.as_ptr()).is_red;
                    (*node_a.as_ptr()).is_red = true;
                    if node_c.as_ref().left.is_some() {
                        let mut node_e = (*node_c.as_ptr()).left;
                        if let Some(e) = &mut node_e {
                            (*e.as_ptr()).parent = Some(node_a);
                        }
                        (*node_a.as_ptr()).right = node_e;
                    } else {
                        (*node_a.as_ptr()).right = None;
                    }
                    (*node_c.as_ptr()).left = Some(node_a);
                    (*node_a.as_ptr()).parent = Some(node_c);
                    (*node_c.as_ptr()).parent = None;
                    (*fixed_head.as_ptr()).left = Some(node_c);
                    (*fixed_head.as_ptr()).left
                }
            }
        }

        /// Rotate right without parent
        /// A is root
        ///
        /// ```text
        ///              A               B
        ///            // \             / \\
        ///            B   C     =>    E    A
        ///          // \                  / \
        ///         E    D                D   C
        /// ```
        ///
        /// Rotate right with parent
        ///
        /// ```text
        ///                P               P
        ///                |               |
        ///                A               B
        ///              // \             / \\
        ///              B   C     =>    E    A
        ///            // \                  / \
        ///           E    D                D   C
        ///
        /// ```
        unsafe fn rotate_right(&mut self, node_a: NonNull<Node<T>>) -> Link<T> {
            unsafe {
                if let Some(parent) = (*node_a.as_ptr()).parent {
                    let mut node_a_from_left = false;
                    if let Some(p_node_a) = (*parent.as_ptr()).left
                        && std::ptr::eq(p_node_a.as_ptr(), node_a.as_ptr())
                    {
                        node_a_from_left = true;
                    }
                    let node_a = if node_a_from_left {
                        (*parent.as_ptr()).left.unwrap()
                    } else {
                        (*parent.as_ptr()).right.unwrap()
                    };
                    let node_b = (*node_a.as_ptr()).left.unwrap();
                    (*node_b.as_ptr()).parent = Some(parent);
                    (*node_b.as_ptr()).is_red = (*node_a.as_ptr()).is_red;
                    (*node_a.as_ptr()).is_red = true;
                    if node_b.as_ref().right.is_some() {
                        let mut node_d = (*node_b.as_ptr()).right;
                        if let Some(d) = &mut node_d {
                            (*d.as_ptr()).parent = Some(node_a);
                        }
                        (*node_a.as_ptr()).left = node_d;
                    } else {
                        (*node_a.as_ptr()).left = None;
                    }
                    (*node_b.as_ptr()).right = Some(node_a);
                    (*node_a.as_ptr()).parent = Some(node_b);
                    if node_a_from_left {
                        (*parent.as_ptr()).left = Some(node_b);
                        (*parent.as_ptr()).left
                    } else {
                        (*parent.as_ptr()).right = Some(node_b);
                        (*parent.as_ptr()).right
                    }
                } else {
                    let fixed_head = self.fixed_head.unwrap();
                    let node_a = (*fixed_head.as_ptr()).left.unwrap();
                    let node_b = (*node_a.as_ptr()).left.unwrap();
                    (*node_b.as_ptr()).is_red = (*node_a.as_ptr()).is_red;
                    (*node_a.as_ptr()).is_red = true;
                    if node_b.as_ref().right.is_some() {
                        let mut node_d = (*node_b.as_ptr()).right;
                        if let Some(d) = &mut node_d {
                            (*d.as_ptr()).parent = Some(node_a);
                        }
                        (*node_a.as_ptr()).left = node_d;
                    } else {
                        (*node_a.as_ptr()).left = None;
                    }
                    (*node_b.as_ptr()).right = Some(node_a);
                    (*node_a.as_ptr()).parent = Some(node_b);
                    (*node_b.as_ptr()).parent = None;
                    (*fixed_head.as_ptr()).left = Some(node_b);
                    (*fixed_head.as_ptr()).left
                }
            }
        }

        /// Flip color
        ///
        /// ```text
        ///             |          ||
        ///             A    =>    A
        ///           // \\       / \
        ///          B    C      B   C
        ///
        /// ```
        unsafe fn flip_colors(&mut self, mut node: NonNull<Node<T>>) {
            unsafe {
                if node.as_ref().left.is_some() && node.as_ref().right.is_some() {
                    if let Some(ref mut left) = node.as_mut().left {
                        left.as_mut().is_red = false;
                    }
                    if let Some(ref mut right) = node.as_mut().right {
                        right.as_mut().is_red = false;
                    }
                    node.as_mut().is_red = true;

                    if (*node.as_ptr()).parent.is_none() {
                        node.as_mut().is_red = false;
                    }
                }
            }
        }

        unsafe fn check_put_balancing(&mut self, node: NonNull<Node<T>>) -> OperationPut {
            unsafe {
                if node.as_ref().right.is_some() {
                    let r = node.as_ref().right.unwrap();
                    if node.as_ref().left.is_some() && !node.as_ref().is_red {
                        let l = node.as_ref().left.unwrap();
                        if l.as_ref().is_red && r.as_ref().is_red {
                            return OperationPut::FlipColors;
                        }
                    }
                    if r.as_ref().is_red {
                        return OperationPut::Left;
                    }
                }
                if node.as_ref().is_red && node.as_ref().left.is_some() {
                    let l = node.as_ref().left.unwrap();
                    if l.as_ref().is_red {
                        return OperationPut::Right;
                    }
                }
                OperationPut::Nothing
            }
        }

        unsafe fn put_balancing(&mut self, next: NonNull<Node<T>>) {
            unsafe {
                let mut next = next;
                loop {
                    match self.check_put_balancing(next) {
                        OperationPut::Left => {
                            if (*next.as_ptr()).is_red {
                                if let Some(n) = self.rotate_left_right_flip_color(next) {
                                    next = n;
                                }
                            } else {
                                if let Some(n) = self.rotate_left(next) {
                                    next = n;
                                }
                            }
                        }
                        OperationPut::Right => {
                            if (*next.as_ptr()).parent.is_some() {
                                let node_a = (*next.as_ptr()).parent.unwrap();
                                if let Some(n) = self.rotate_right(node_a) {
                                    next = n;
                                }
                            }
                        }
                        OperationPut::FlipColors => {
                            self.flip_colors(next);
                            if (*next.as_ptr()).parent.is_some() {
                                next = (*next.as_ptr()).parent.unwrap();
                            } else {
                                break;
                            }
                        }
                        OperationPut::Nothing => {
                            break;
                        }
                    }
                }
            }
        }

        unsafe fn find_put_parent_candidate(&mut self, parent: Link<T>, elem: &T) -> Link<T> {
            unsafe {
                if let Some(parent) = parent {
                    match elem.cmp(&parent.as_ref().value) {
                        Ordering::Equal => None,
                        Ordering::Less => {
                            if (*parent.as_ptr()).left.is_some() {
                                self.find_put_parent_candidate((*parent.as_ptr()).left, elem)
                            } else {
                                Some(parent)
                            }
                        }
                        Ordering::Greater => {
                            if (*parent.as_ptr()).right.is_some() {
                                self.find_put_parent_candidate((*parent.as_ptr()).right, elem)
                            } else {
                                Some(parent)
                            }
                        }
                    }
                } else {
                    parent
                }
            }
        }

        unsafe fn attach_node(&mut self, parent: NonNull<Node<T>>, elem: T) -> bool {
            unsafe {
                match elem.cmp(&parent.as_ref().value) {
                    Ordering::Equal => false,
                    Ordering::Less => {
                        (*parent.as_ptr()).left = Node::new_red(elem, parent);
                        true
                    }
                    Ordering::Greater => {
                        (*parent.as_ptr()).right = Node::new_red(elem, parent);
                        true
                    }
                }
            }
        }

        /// Returns the default iterator over the tree.
        ///
        /// The default traversal is in-order (`LNR`), so values are yielded in
        /// ascending order.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([3, 1, 2]);
        ///
        /// let values: Vec<i32> = tree.iter().copied().collect();
        ///
        /// assert_eq!(values, vec![1, 2, 3]);
        /// ```
        pub fn iter(&self) -> IterInOrder<'_, T> {
            self.iter_inorder()
        }

        /// Returns an in-order (`LNR`) iterator.
        ///
        /// Values are yielded in ascending order.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([3, 1, 2]);
        ///
        /// assert_eq!(
        ///     tree.iter_inorder().copied().collect::<Vec<_>>(),
        ///     vec![1, 2, 3]
        /// );
        /// ```
        pub fn iter_inorder(&self) -> IterInOrder<'_, T> {
            unsafe { IterInOrder::new(leftmost_child_in_order(self.get_root()), self.count) }
        }

        /// Returns a reverse in-order (`RNL`) iterator.
        ///
        /// Values are yielded in descending order.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([3, 1, 2]);
        ///
        /// assert_eq!(
        ///     tree.iter_reverse_inorder().copied().collect::<Vec<_>>(),
        ///     vec![3, 2, 1]
        /// );
        /// ```
        pub fn iter_reverse_inorder(&self) -> IterReverseInOrder<'_, T> {
            unsafe {
                IterReverseInOrder::new(
                    rightmost_child_reverse_in_order(self.get_root()),
                    self.count,
                )
            }
        }

        /// Returns a pre-order (`NLR`) iterator.
        ///
        /// The current node is visited before its left and right subtrees.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([4, 2, 6, 1, 3, 5, 7]);
        ///
        /// let values: Vec<i32> = tree.iter_preorder().copied().collect();
        ///
        /// assert_eq!(values.len(), tree.len());
        /// ```
        pub fn iter_preorder(&self) -> IterPreOrder<'_, T> {
            IterPreOrder::new(self.get_root(), self.count)
        }

        /// Returns a post-order (`LRN`) iterator.
        ///
        /// The left and right subtrees are visited before the current node.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([4, 2, 6, 1, 3, 5, 7]);
        ///
        /// let values: Vec<i32> = tree.iter_postorder().copied().collect();
        ///
        /// assert_eq!(values.len(), tree.len());
        /// ```
        pub fn iter_postorder(&self) -> IterPostOrder<'_, T> {
            unsafe {
                let first = self.get_root().map(|root| leaf_post_order(root));
                IterPostOrder::new(first, self.count)
            }
        }

        /// Returns all values in level-order traversal.
        ///
        /// Nodes are visited level by level, starting from the root.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([4, 2, 6, 1, 3, 5, 7]);
        ///
        /// let values = tree.iter_level_order();
        ///
        /// assert_eq!(values.len(), tree.len());
        /// ```
        pub fn iter_level_order(&self) -> Vec<&T> {
            let mut ret: Vec<&T> = vec![];
            if let Some(root) = self.get_root() {
                iter_level_order_impl(root, &mut ret);
            }
            ret
        }
    }

    impl<'a, T: Ord + Default> std::iter::IntoIterator for &'a RedBlackTree<T> {
        type IntoIter = IterInOrder<'a, T>;
        type Item = &'a T;

        fn into_iter(self) -> Self::IntoIter {
            self.iter()
        }
    }

    impl<T: Ord + Default> Drop for RedBlackTree<T> {
        fn drop(&mut self) {
            unsafe {
                if let Some(fixed_head) = self.fixed_head {
                    self.remove_tree((*fixed_head.as_ptr()).left);
                    let _ = Box::from_raw(fixed_head.as_ptr());
                }
                self.fixed_head = None;
            }
        }
    }

    fn find_node<T: Ord>(fromnode: Link<T>, value: &T) -> Link<T> {
        unsafe {
            if let Some(fromnode) = fromnode {
                match value.cmp(&(*fromnode.as_ptr()).value) {
                    Ordering::Equal => Some(fromnode),
                    Ordering::Less => find_node((*fromnode.as_ptr()).left, value),
                    Ordering::Greater => find_node((*fromnode.as_ptr()).right, value),
                }
            } else {
                fromnode
            }
        }
    }

    fn helper_display_tree<T: Display>(node: NonNull<Node<T>>) -> String {
        unsafe {
            let mut s: String = "".into();
            let color = if (*node.as_ptr()).is_red {
                "[color=\"red\"]"
            } else {
                "[color=\"black\"]"
            };

            if let Some(left) = (*node.as_ptr()).left {
                s.push_str(&format!(
                    "\t{n1}->{n2} {color1}; {n1} {color1}; {n2} {color2};\n",
                    n1 = (*node.as_ptr()).value,
                    n2 = (*left.as_ptr()).value,
                    color1 = color,
                    color2 = if (*left.as_ptr()).is_red {
                        "[color=\"red\"]"
                    } else {
                        "[color=\"black\"]"
                    },
                ));
                s.push_str(&helper_display_tree(left));
            } else if (*node.as_ptr()).right.is_some() {
                s.push_str(&format!(
                    "\t{n1}->node_null_{n1} [color=\"grey\"]; {n1} {color1};\n",
                    n1 = (*node.as_ptr()).value,
                    color1 = color
                ));
                s.push_str(&format!(
                    "\tnode_null_{n1}[label=\"null\"]\n",
                    n1 = (*node.as_ptr()).value
                ));
            }

            if let Some(right) = (*node.as_ptr()).right {
                s.push_str(&format!(
                    "\t{n1}->{n2} {color1}; {n1} {color1}; {n2} {color2};\n",
                    n1 = (*node.as_ptr()).value,
                    n2 = (*right.as_ptr()).value,
                    color2 = if (*right.as_ptr()).is_red {
                        "[color=\"red\"]"
                    } else {
                        "[color=\"black\"]"
                    },
                    color1 = color
                ));
                s.push_str(&helper_display_tree(right));
            } else {
                s.push_str(&format!(
                    "\t{n1}->node_null_{n1} [color=\"grey\"]; {n1} {color1};\n",
                    n1 = (*node.as_ptr()).value,
                    color1 = color
                ));
                s.push_str(&format!(
                    "\tnode_null_{}[label=\"null\"]\n",
                    (*node.as_ptr()).value
                ));
            }
            s
        }
    }

    impl<T: Ord + Default> Default for RedBlackTree<T> {
        fn default() -> Self {
            Self::new()
        }
    }

    impl<T: Ord + Default + Clone> Clone for RedBlackTree<T> {
        fn clone(&self) -> Self {
            let mut new_list = Self::new();
            for value in self {
                new_list.insert(value.clone());
            }
            new_list
        }
    }

    impl<T: Ord + Default> Extend<T> for RedBlackTree<T> {
        fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
            for value in iter {
                self.insert(value);
            }
        }
    }

    impl<T: Ord + Default> FromIterator<T> for RedBlackTree<T> {
        fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
            let mut list = Self::new();
            list.extend(iter);
            list
        }
    }

    impl<T: Ord + Default + Debug> Debug for RedBlackTree<T> {
        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
            f.debug_list().entries(self).finish()
        }
    }

    impl<T: Ord + Default> PartialEq for RedBlackTree<T> {
        fn eq(&self, other: &Self) -> bool {
            self.len() == other.len() && self.iter_inorder().eq(other.iter_inorder())
        }
    }

    impl<T: Ord + Default> Eq for RedBlackTree<T> {}

    impl<T: Ord + Default> PartialOrd for RedBlackTree<T> {
        fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
            Some(self.cmp(other))
        }
    }

    impl<T: Ord + Default> Ord for RedBlackTree<T> {
        fn cmp(&self, other: &Self) -> Ordering {
            self.iter_inorder().cmp(other.iter_inorder())
        }
    }

    impl<T: Ord + Default + std::hash::Hash> std::hash::Hash for RedBlackTree<T> {
        fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
            self.len().hash(state);
            for item in self {
                item.hash(state);
            }
        }
    }
}

6. Динамический набор интервалов или границ

Когда элементы постоянно добавляются и удаляются, но нужен отсортированный порядок.

Новые цены постоянно появляются, часть заявок отменяется, но нам всё время нужно видеть цены в отсортированном порядке.

fn main() {
    let mut prices = RedBlackTree::new();
    // Приходят новые заявки.
    prices.insert(105);
    prices.insert(98);
    prices.insert(110);
    prices.insert(102);
    println!("Текущие цены:");
    for price in prices.iter() {
        println!("{price}");
    }
    // Пришла новая заявка.
    prices.insert(100);
    // Заявку по цене 105 отменили.
    prices.remove(&105);
    // Появились ещё две заявки.
    prices.insert(115);
    prices.insert(97);
    println!("\nПосле изменений:");

    for price in prices.iter() {
        println!("{price}");
    }

    println!("\nМинимальная цена: {:?}", prices.first());
    println!("Максимальная цена: {:?}", prices.last());
}














/// -------------------------------------------
/// Implementation RBT
/// -------------------------------------------


pub use tree::RedBlackTree;
pub use iter::{IterInOrder, Range};
pub use iter::IterPreOrder;
pub use iter::IterReverseInOrder;
pub use iter::IterPostOrder;
 
pub mod iter{
    use std::ptr::NonNull;

    use crate::node::{Link, Node};

    ///```text
    ///
    ///            4
    ///          /   \
    ///         2     9
    ///        / \   //\
    ///       1   3  7   10
    ///             / \
    ///            6   8
    ///```
    ///    Depth-First Search / Pre-order (NLR):     4, 2, 1, 3, 9, 7, 6, 8, 10
    ///    Depth-First Search / In-order (LNR):      1, 2, 3, 4, 6, 7, 8, 9, 10
    ///    Depth-First Search / Post-order (LRN):    1, 3, 2, 6, 8, 7, 10, 9, 4
    ///    Breadth-First Search / Level-order:       4, 2, 9, 1, 3, 7, 10, 6, 8 
    pub use dfs_in_order::{IterInOrder, Range};

    pub(crate) use dfs_in_order::{leftmost_child_in_order, successor_of_node_in_order};

    mod dfs_in_order {
        use super::{Link, Node, NonNull};
        use std::iter::FusedIterator;
        use std::marker::PhantomData;

        /// Returns the next node in an in-order (`LNR`) traversal.
        ///
        /// # Safety
        ///
        /// `node` must point to a live node that belongs to the current tree, and
        /// all parent/child links reachable from it must be valid.
        pub unsafe fn successor_of_node_in_order<T>(node: NonNull<Node<T>>) -> Link<T> {
            unsafe {
                if node.as_ref().right.is_some() {
                    // If a right subtree exists, the successor is its leftmost node.
                    leftmost_child_in_order(node.as_ref().right)
                } else {
                    // Otherwise, walk up through parent links until the current
                    // node is found in a left subtree.
                    parent_with_left(node)
                }
            }
        }

        /// Returns the leftmost node reachable from `node`.
        ///
        /// Returns `None` when `node` is `None`.
        ///
        /// # Safety
        ///
        /// Every pointer reachable through `left` links must refer to a live node.
        pub unsafe fn leftmost_child_in_order<T>(node: Link<T>) -> Link<T> {
            unsafe {
                if let Some(node) = node {
                    if node.as_ref().left.is_none() {
                        Some(node)
                    } else {
                        leftmost_child_in_order(node.as_ref().left)
                    }
                } else {
                    node
                }
            }
        }

        /// Walks up the parent chain until an ancestor is reached from its left child.
        ///
        /// # Safety
        ///
        /// `node` and all parent links traversed by this function must be valid.
        unsafe fn parent_with_left<T>(node: NonNull<Node<T>>) -> Link<T> {
            unsafe {
                let parent = node.as_ref().parent;
                if let Some(parent) = parent
                    && let Some(left) = parent.as_ref().left
                {
                    if std::ptr::eq(left.as_ptr(), node.as_ptr()) {
                        return Some(parent);
                    }
                    return parent_with_left(parent);
                }
                // No parent means that the root has been reached.
                None
            }
        }

        /// Iterator over a tree in in-order (`Left -> Node -> Right`, or `LNR`).
        ///
        /// For a binary search tree, this traversal yields values in ascending order.
        pub struct IterInOrder<'a, T> {
            current_node: Link<T>,
            count: usize,
            elem: Option<&'a T>,
            _boo: PhantomData<&'a T>,
        }

        impl<'a, T> IterInOrder<'a, T> {
            /// Creates an in-order iterator starting at `node`.
            pub(crate) fn new(node: Link<T>, count: usize) -> Self {
                Self {
                    current_node: node,
                    count,
                    elem: None,
                    _boo: PhantomData,
                }
            }
        }

        impl<'a, T> Iterator for IterInOrder<'a, T> {
            type Item = &'a T;

            fn next(&mut self) -> Option<Self::Item> {
                if self.count > 0 {
                    self.count -= 1;
                    if let Some(node) = self.current_node {
                        unsafe {
                            self.elem = Some(&node.as_ref().value);
                            self.current_node = successor_of_node_in_order(node);
                        }
                    } else {
                        self.elem = None;
                    }
                } else {
                    self.elem = None;
                }
                self.elem
            }

            fn size_hint(&self) -> (usize, Option<usize>) {
                (self.count, Some(self.count))
            }
        }

        impl<'a, T> ExactSizeIterator for IterInOrder<'a, T> {
            fn len(&self) -> usize {
                self.count
            }
        }

        impl<'a, T> FusedIterator for IterInOrder<'a, T> {}

        /// A lazy iterator over an inclusive range of values in a [`crate::RedBlackTree`].
        ///
        /// `Range` is created by [`crate::RedBlackTree::range`]. It yields references to
        /// values in ascending order, starting from the first value greater than or
        /// equal to the lower bound and stopping after the upper bound.
        ///
        /// The iterator does not allocate an intermediate collection. Values are
        /// produced one at a time as the iterator advances.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([1, 3, 5, 7, 9, 11]);
        ///
        /// let values: Vec<_> = tree
        ///     .range(&3, &9)
        ///     .copied()
        ///     .collect();
        ///
        /// assert_eq!(values, vec![3, 5, 7, 9]);
        /// ```
        ///
        /// The iterator can be combined with standard iterator adapters:
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend(1..=100);
        ///
        /// let values: Vec<_> = tree
        ///     .range(&20, &80)
        ///     .take(3)
        ///     .copied()
        ///     .collect();
        ///
        /// assert_eq!(values, vec![20, 21, 22]);
        /// ```
        pub struct Range<'a, T> {
            current_node: Link<T>,
            end_node: Link<T>,
            _marker: PhantomData<&'a T>,
        }

        impl<'a, T: Ord> Range<'a, T> {
            pub(crate) fn new(root: Link<T>, min: &T, max: &T) -> Self {
                if min > max {
                    return Self {
                        current_node: None,
                        end_node: None,
                        _marker: PhantomData,
                    };
                }

                unsafe {
                    let mut current = root;
                    let mut start: Link<T> = None;

                    // First node >= min.
                    while let Some(node) = current {
                        match node.as_ref().value.cmp(min) {
                            std::cmp::Ordering::Less => {
                                current = node.as_ref().right;
                            }

                            std::cmp::Ordering::Equal => {
                                start = Some(node);
                                break;
                            }

                            std::cmp::Ordering::Greater => {
                                start = Some(node);
                                current = node.as_ref().left;
                            }
                        }
                    }

                    current = root;

                    let mut end: Link<T> = None;

                    // First node > max.
                    while let Some(node) = current {
                        match node.as_ref().value.cmp(max) {
                            std::cmp::Ordering::Less | std::cmp::Ordering::Equal => {
                                current = node.as_ref().right;
                            }

                            std::cmp::Ordering::Greater => {
                                end = Some(node);
                                current = node.as_ref().left;
                            }
                        }
                    }

                    Self {
                        current_node: start,
                        end_node: end,
                        _marker: PhantomData,
                    }
                }
            }
        }

        impl<'a, T> Iterator for Range<'a, T> {
            type Item = &'a T;

            fn next(&mut self) -> Option<Self::Item> {
                let node = self.current_node?;

                if self.end_node == Some(node) {
                    self.current_node = None;
                    return None;
                }

                unsafe {
                    let value = &node.as_ref().value;

                    self.current_node = successor_of_node_in_order(node);

                    Some(value)
                }
            }
        }
    }

    pub use dfs_reverse_in_order::IterReverseInOrder;

    pub(crate) use dfs_reverse_in_order::{
        rightmost_child_reverse_in_order, successor_of_node_reverse_in_order,
    };

    mod dfs_reverse_in_order {
        use super::{Link, Node, NonNull};
        use std::marker::PhantomData;

        /// Returns the next node in reverse in-order (`Right -> Node -> Left`, or `RNL`).
        ///
        /// # Safety
        ///
        /// `node` must point to a live node that belongs to the current tree, and
        /// all parent/child links reachable from it must be valid.
        pub unsafe fn successor_of_node_reverse_in_order<T>(node: NonNull<Node<T>>) -> Link<T> {
            unsafe {
                if node.as_ref().left.is_some() {
                    // After the current node, descend into the left subtree and
                    // choose its rightmost node.
                    rightmost_child_reverse_in_order(node.as_ref().left)
                } else {
                    // Without a left subtree, walk upward until reaching an
                    // ancestor from its right subtree.
                    parent_with_right(node)
                }
            }
        }

        /// Returns the rightmost node reachable from `node`.
        ///
        /// Returns `None` when `node` is `None`.
        ///
        /// # Safety
        ///
        /// Every pointer reachable through `right` links must refer to a live node.
        pub unsafe fn rightmost_child_reverse_in_order<T>(node: Link<T>) -> Link<T> {
            unsafe {
                if let Some(node) = node {
                    if node.as_ref().right.is_none() {
                        Some(node)
                    } else {
                        rightmost_child_reverse_in_order(node.as_ref().right)
                    }
                } else {
                    None
                }
            }
        }

        /// Walks up the parent chain until an ancestor is reached from its right child.
        ///
        /// # Safety
        ///
        /// `node` and all parent links traversed by this function must be valid.
        unsafe fn parent_with_right<T>(node: NonNull<Node<T>>) -> Link<T> {
            unsafe {
                let parent = node.as_ref().parent;

                if let Some(parent) = parent
                    && let Some(right) = parent.as_ref().right
                {
                    if std::ptr::eq(right.as_ptr(), node.as_ptr()) {
                        return Some(parent);
                    }

                    return parent_with_right(parent);
                }

                None
            }
        }

        /// Iterator over a tree in reverse in-order (`Right -> Node -> Left`, or `RNL`).
        ///
        /// For a binary search tree, this traversal yields values in descending order.
        pub struct IterReverseInOrder<'a, T> {
            current_node: Link<T>,
            count: usize,
            elem: Option<&'a T>,
            _boo: PhantomData<&'a T>,
        }

        impl<'a, T> IterReverseInOrder<'a, T> {
            /// Creates a reverse in-order iterator starting at `node`.
            pub(crate) fn new(node: Link<T>, count: usize) -> Self {
                Self {
                    current_node: node,
                    count,
                    elem: None,
                    _boo: PhantomData,
                }
            }
        }

        impl<'a, T> Iterator for IterReverseInOrder<'a, T> {
            type Item = &'a T;

            fn next(&mut self) -> Option<Self::Item> {
                if self.count > 0 {
                    self.count -= 1;

                    if let Some(node) = self.current_node {
                        unsafe {
                            self.elem = Some(&node.as_ref().value);
                            self.current_node = successor_of_node_reverse_in_order(node);
                        }
                    } else {
                        self.elem = None;
                    }
                } else {
                    self.elem = None;
                }

                self.elem
            }

            fn size_hint(&self) -> (usize, Option<usize>) {
                (self.count, Some(self.count))
            }
        }
    }

    pub use dfs_pre_order::IterPreOrder;

    pub(crate) use dfs_pre_order::successor_of_node_pre_order;

    mod dfs_pre_order {
        use super::{Link, Node, NonNull};
        use std::marker::PhantomData;

        /// Returns the next node in a pre-order (`Node -> Left -> Right`, or `NLR`) traversal.
        ///
        /// # Safety
        ///
        /// `node` must point to a live node in the current tree and all traversed
        /// links must be valid.
        pub unsafe fn successor_of_node_pre_order<T>(node: NonNull<Node<T>>) -> Link<T> {
            unsafe {
                if let Some(node) = node.as_ref().left {
                    Some(node)
                } else if let Some(node) = node.as_ref().right {
                    Some(node)
                } else {
                    right_with_parent(node)
                }
            }
        }

        /// Finds the next right subtree by walking through parent links.
        ///
        /// # Safety
        ///
        /// `node` and all parent links traversed by this function must be valid.
        unsafe fn right_with_parent<T>(node: NonNull<Node<T>>) -> Link<T> {
            unsafe {
                if let Some(parent) = node.as_ref().parent {
                    next_right(Some(parent), node)
                } else {
                    None
                }
            }
        }

        /// Searches ancestors for the next unvisited right child.
        ///
        /// # Safety
        ///
        /// `child`, `node`, and all links traversed by this function must be valid.
        unsafe fn next_right<T>(node: Link<T>, child: NonNull<Node<T>>) -> Link<T> {
            unsafe {
                if let Some(n) = node {
                    if let Some(right) = n.as_ref().right {
                        if std::ptr::eq(right.as_ptr(), child.as_ptr()) {
                            next_right(n.as_ref().parent, n)
                        } else {
                            Some(right)
                        }
                    } else {
                        next_right(n.as_ref().parent, n)
                    }
                } else {
                    None
                }
            }
        }

        /// Iterator over a tree in pre-order (`Node -> Left -> Right`, or `NLR`).
        ///
        /// Pre-order traversal visits a node before either of its subtrees.
        pub struct IterPreOrder<'a, T> {
            current_node: Link<T>,
            count: usize,
            elem: Option<&'a T>,
            _boo: PhantomData<&'a T>,
        }

        impl<'a, T> IterPreOrder<'a, T> {
            /// Creates a pre-order iterator starting at `root`.
            pub(crate) fn new(root: Link<T>, count: usize) -> Self {
                Self {
                    current_node: root,
                    count,
                    elem: None,
                    _boo: PhantomData,
                }
            }
        }

        impl<'a, T> Iterator for IterPreOrder<'a, T> {
            type Item = &'a T;

            fn next(&mut self) -> Option<Self::Item> {
                if self.count > 0 {
                    self.count -= 1;
                    if let Some(node) = self.current_node {
                        unsafe {
                            self.elem = Some(&node.as_ref().value);
                            self.current_node = successor_of_node_pre_order(node);
                        }
                    } else {
                        self.elem = None;
                    }
                } else {
                    self.elem = None;
                }
                self.elem
            }

            fn size_hint(&self) -> (usize, Option<usize>) {
                (self.count, Some(self.count))
            }
        }
    }

    pub use dfs_post_order::IterPostOrder;

    pub(crate) use dfs_post_order::{leaf_post_order, successor_of_node_post_order};

    mod dfs_post_order {
        use super::{Link, Node, NonNull};
        use std::marker::PhantomData;

        /// Returns the next node in a post-order (`Left -> Right -> Node`, or `LRN`) traversal.
        ///
        /// # Safety
        ///
        /// `current_node` must point to a live node in the current tree and all
        /// traversed parent/child links must be valid.
        pub unsafe fn successor_of_node_post_order<T>(current_node: NonNull<Node<T>>) -> Link<T> {
            unsafe {
                if let Some(parent) = current_node.as_ref().parent {
                    if let Some(right) = parent.as_ref().right {
                        if std::ptr::eq(current_node.as_ptr(), right.as_ptr()) {
                            Some(parent)
                        } else {
                            Some(leaf_post_order(right))
                        }
                    } else {
                        Some(parent)
                    }
                } else {
                    None
                }
            }
        }

        /// Returns the first leaf visited by a post-order traversal starting at `node`.
        ///
        /// # Safety
        ///
        /// `node` must point to a live node and all descendant links traversed by
        /// this function must be valid.
        pub unsafe fn leaf_post_order<T>(node: NonNull<Node<T>>) -> NonNull<Node<T>> {
            unsafe {
                if let Some(left) = node.as_ref().left {
                    leaf_post_order(left)
                } else if let Some(right) = node.as_ref().right {
                    leaf_post_order(right)
                } else {
                    node
                }
            }
        }

        /// Iterator over a tree in post-order (`Left -> Right -> Node`, or `LRN`).
        ///
        /// Post-order traversal visits both subtrees before the current node.
        pub struct IterPostOrder<'a, T> {
            current_node: Link<T>,
            count: usize,
            _boo: PhantomData<&'a T>,
        }

        impl<'a, T> IterPostOrder<'a, T> {
            /// Creates a post-order iterator starting at the first post-order node.
            pub(crate) fn new(root: Link<T>, count: usize) -> Self {
                Self {
                    current_node: root,
                    count,
                    _boo: PhantomData,
                }
            }
        }

        impl<'a, T> Iterator for IterPostOrder<'a, T> {
            type Item = &'a T;

            fn next(&mut self) -> Option<Self::Item> {
                if self.count == 0 {
                    return None;
                }

                let node = self.current_node?;

                unsafe {
                    let value = &node.as_ref().value;
                    self.current_node = successor_of_node_post_order(node);
                    self.count -= 1;
                    Some(value)
                }
            }

            fn size_hint(&self) -> (usize, Option<usize>) {
                (self.count, Some(self.count))
            }
        }
    }

    /// Breadth-First Search
    mod bfs {
        use super::{Node, NonNull};
        use std::collections::VecDeque;

        /// Appends tree values to `ret` in breadth-first / level-order.
        pub fn iter_level_order_impl<T>(root: NonNull<Node<T>>, ret: &mut Vec<&T>) {
            let mut deque: VecDeque<NonNull<Node<T>>> = VecDeque::new();
            unsafe {
                deque.push_back(root);
                let mut node: NonNull<Node<T>>;
                while !deque.is_empty() {
                    node = deque.pop_front().unwrap();
                    ret.push(&node.as_ref().value);
                    if let Some(left) = node.as_ref().left {
                        deque.push_back(left);
                    }
                    if let Some(right) = node.as_ref().right {
                        deque.push_back(right);
                    }
                }
            }
        }
    }

    pub(crate) use bfs::iter_level_order_impl;
}

/// Internal node representation used by the Red-Black Tree.
///
/// Nodes are allocated on the heap and connected using [`NonNull`] pointers.
/// The tree owns the allocated nodes and is responsible for releasing them.
///
/// `Node` and [`Link`] are crate-private implementation details and are not
/// exposed through the public API.
pub mod node{

    use std::ptr::NonNull;

    /// A single node in the Red-Black Tree.
    ///
    /// Each node stores:
    ///
    /// - a link to its left child;
    /// - a link to its right child;
    /// - a link to its parent;
    /// - its Red-Black color;
    /// - the stored value.
    ///
    /// Tree links are represented by [`Link<T>`], which is an
    /// `Option<NonNull<Node<T>>>`.
    ///
    /// A `None` link represents the absence of a parent or child, while
    /// `Some(pointer)` refers to another allocated node.
    ///
    /// Memory ownership is managed by [`crate::RedBlackTree`]. The pointers stored
    /// here are non-owning links between nodes.
    #[derive(Debug)]
    pub(crate) struct Node<T> {
        /// Left child of this node.
        pub(crate) left: Link<T>,

        /// Right child of this node.
        pub(crate) right: Link<T>,

        /// Parent of this node.
        ///
        /// The root node has no parent.
        pub(crate) parent: Link<T>,

        /// Red-Black color of the node.
        ///
        /// `true` means red and `false` means black.
        pub(crate) is_red: bool,

        /// Value stored in this node.
        pub(crate) value: T,
    }

    /// A link between nodes in the tree.
    ///
    /// `None` represents a missing parent or child.
    ///
    /// `Some(ptr)` contains a non-null pointer to another allocated [`Node`].
    ///
    /// Using `Option<NonNull<Node<T>>>` allows the implementation to represent
    /// nullable tree links while keeping direct pointer-based navigation between
    /// parents and children.
    pub(crate) type Link<T> = Option<NonNull<Node<T>>>;

    impl<T: Default> Node<T> {
        /// Creates the sentinel head node together with the initial tree root.
        ///
        /// The sentinel does not represent a value stored by the user. Its
        /// `value` field is initialized with [`Default::default`] and its left
        /// child becomes the first actual node in the tree.
        ///
        /// The initial root node is created as black, as required by the
        /// Red-Black Tree invariants.
        ///
        /// # Returns
        ///
        /// A link to the newly allocated sentinel node.
        ///
        /// # Implementation
        ///
        /// Both the sentinel and the root node are allocated on the heap.
        /// Ownership of these allocations is transferred to the tree and later
        /// recovered when the tree releases its nodes.
        pub(crate) fn new_fixed_head(value: T) -> Link<T> {
            let fixed_head = Box::into_non_null(Box::new(Self {
                left: None,
                right: None,
                parent: None,
                is_red: false,
                value: T::default(),
            }));
            unsafe {
                (*fixed_head.as_ptr()).left = Node::new_black(value);
            }
            Some(fixed_head)
        }
    }

    impl<T> Node<T> {
        /// Allocates a new black node.
        ///
        /// The node is created without a parent or children.
        ///
        /// # Returns
        ///
        /// A non-null link to the newly allocated node.
        ///
        /// The allocation becomes owned by the tree and must eventually be
        /// released by the tree implementation.
        pub(crate) fn new_black(value: T) -> Link<T> {
            let new = Box::into_non_null(Box::new(Self {
                left: None,
                right: None,
                parent: None,
                is_red: false,
                value,
            }));

            Some(new)
        }

        /// Allocates a new red node with the specified parent.
        ///
        /// Newly inserted Red-Black Tree nodes are initially red. The balancing
        /// algorithm may later recolor the node or rotate the surrounding
        /// subtree.
        ///
        /// The new node has no children.
        ///
        /// # Parameters
        ///
        /// - `value` — value stored in the node.
        /// - `parent` — non-null pointer to the node's parent.
        ///
        /// # Returns
        ///
        /// A non-null link to the newly allocated node.
        ///
        /// The allocation becomes owned by the tree and must eventually be
        /// released by the tree implementation.
        pub(crate) fn new_red(value: T, parent: NonNull<Node<T>>) -> Link<T> {
            let new = Box::into_non_null(Box::new(Self {
                left: None,
                right: None,
                parent: Some(parent),
                is_red: true,
                value,
            }));

            Some(new)
        }
    }
}


pub mod validation{
    use crate::node::Link;
    use crate::tree::RedBlackTree;

    impl<T: Ord + Default> RedBlackTree<T> {
        // red-red violations,
        // min black-height,
        // max black-height,
        // BST ordering,
        // parent links,
        // reachable node count
        unsafe fn validate(
            node: &Link<T>,
            expected_parent: Link<T>,
            parent_is_red: bool,
            black_height: usize,
            min: Option<&T>,
            max: Option<&T>,
        ) -> (usize, usize, usize, bool, bool, usize) {
            unsafe {
                if let Some(n) = node {
                    let value = &n.as_ref().value;

                    // 1. Check parent
                    let parent_valid = match (n.as_ref().parent, expected_parent) {
                        (None, None) => true,

                        (Some(actual), Some(expected)) => {
                            std::ptr::eq(actual.as_ptr(), expected.as_ptr())
                        }

                        _ => false,
                    };

                    // 2. Check BST ordering
                    if let Some(min) = min
                        && value <= min
                    {
                        return (0, 0, 0, false, parent_valid, 1);
                    }

                    if let Some(max) = max
                        && value >= max
                    {
                        return (0, 0, 0, false, parent_valid, 1);
                    }

                    let is_red = n.as_ref().is_red;

                    // 3. A red node cannot have a red parent.
                    let red_red = if parent_is_red && is_red { 1 } else { 0 };

                    // 4. Black height
                    let black_height = if is_red {
                        black_height
                    } else {
                        black_height + 1
                    };

                    let left = Self::validate(
                        &n.as_ref().left,
                        Some(*n),
                        is_red,
                        black_height,
                        min,
                        Some(value),
                    );

                    let right = Self::validate(
                        &n.as_ref().right,
                        Some(*n),
                        is_red,
                        black_height,
                        Some(value),
                        max,
                    );

                    (
                        red_red + left.0 + right.0,
                        std::cmp::min(left.1, right.1),
                        std::cmp::max(left.2, right.2),
                        left.3 && right.3,
                        parent_valid && left.4 && right.4,
                        1 + left.5 + right.5,
                    )
                } else {
                    (0, black_height, black_height, true, true, 0)
                }
            }
        }

        pub fn is_valid(&self) -> bool {
            unsafe {
                // tree is empty
                if self.count == 0 {
                    return match self.fixed_head {
                        None => true,

                        Some(fixed_head) => (*fixed_head.as_ptr()).left.is_none(),
                    };
                }

                // count > 0, so sentinel must exist.
                let Some(fixed_head) = self.fixed_head else {
                    return false;
                };

                // And root must exist.
                let root_link = (*fixed_head.as_ptr()).left;

                let Some(root) = root_link else {
                    return false;
                };

                // Root is always BLACK
                if root.as_ref().is_red {
                    return false;
                }

                // Root has no parent
                if root.as_ref().parent.is_some() {
                    return false;
                }

                let result = Self::validate(&root_link, None, false, 0, None, None);

                let red_red = result.0;
                let black_height_min = result.1;
                let black_height_max = result.2;
                let bst_valid = result.3;
                let parents_valid = result.4;
                let reachable_nodes = result.5;

                red_red == 0
                    && black_height_min == black_height_max
                    && bst_valid
                    && parents_valid
                    && reachable_nodes == self.count
            }
        }
    }
}


pub mod tree{
    use std::cmp::Ordering;
    use std::fmt::{Debug, Display};

    use crate::node::{Link, Node};

    use std::marker::PhantomData;
    use std::ptr::NonNull;

    use crate::iter::{IterInOrder, Range, leftmost_child_in_order, successor_of_node_in_order};

    use crate::iter::{
        IterReverseInOrder, rightmost_child_reverse_in_order, successor_of_node_reverse_in_order,
    };

    use crate::iter::{IterPreOrder, successor_of_node_pre_order};

    use crate::iter::{IterPostOrder, leaf_post_order, successor_of_node_post_order};

    use crate::iter::iter_level_order_impl;

    /// A self-balancing Red-Black Tree.
    ///
    /// `RedBlackTree` stores unique values in sorted order.
    ///
    /// Insert, lookup and removal operations have logarithmic
    /// expected tree height due to Red-Black Tree balancing.
    ///
    /// # Examples
    ///
    /// ```
    /// use rbtree_extended::RedBlackTree;
    ///
    /// let mut tree = RedBlackTree::new();
    ///
    /// tree.insert(3);
    /// tree.insert(1);
    /// tree.insert(2);
    ///
    /// assert_eq!(tree.len(), 3);
    /// assert!(tree.contains(&2));
    /// ```
    pub struct RedBlackTree<T: Ord + Default> {
        pub(crate) fixed_head: Link<T>,
        pub(crate) count: usize,
        _marker: PhantomData<T>,
    }

    enum OperationPut {
        Left,
        Right,
        FlipColors,
        Nothing,
    }

    enum OperationRemove {
        RedLeaf,
        BlackLeaf,
        NodeWithChildren,
        BlackNodeWithRedLeaf,
    }

    enum OperationRemoveBlackLeaf {
        LeftRedABlackBRedCleaf,                      // 2.1.1.1
        RightRedABlackBRedCleaf,                     // 2.1.1.2
        LeftRedABlackBleaf,                          // 2.1.2.1
        RightRedABlackBleaf,                         // 2.1.2.2
        BlackARedBWithBlackChildrenLeaf,             // 2.2.4
        BlackARedBWithBlackChildrenRightHaveRedLeaf, // 2.2.1
        BlackALeftBlackBRedDleaf,                    // 2.3.1.1
        BlackARightBlackBRedDleaf,                   // 2.3.1.2
        BlackALeftBlackBleaf,                        // 2.3.2.1
        BlackARightBlackBleaf,                       // 2.3.2.2
        Root,
        Unimplemented,
    }

    impl<T: Ord + Default + Display> RedBlackTree<T> {
        /// Exports the tree in Graphviz DOT format.
        ///
        /// The returned string can be rendered using Graphviz-compatible tools.
        ///
        /// An empty tree produces a valid empty DOT graph.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.insert(10);
        /// tree.insert(5);
        /// tree.insert(20);
        ///
        /// let dot = tree.to_dot();
        ///
        /// println!("{dot}");
        /// ```
        pub fn to_dot(&self) -> String {
            unsafe {
                let Some(fixed_head) = self.fixed_head else {
                    return "digraph Tree {}".into();
                };

                let Some(root) = (*fixed_head.as_ptr()).left else {
                    return "digraph Tree {}".into();
                };

                format!(
                    "\ndigraph Tree {{\n\tratio = fill;\n\tnode [style=filled fontcolor=\"white\"];\n{}}}",
                    helper_display_tree(root)
                )
            }
        }
    }

    impl<T: Ord + Default> RedBlackTree<T> {
        /// Creates an empty Red-Black Tree.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let tree = RedBlackTree::<i32>::new();
        ///
        /// assert!(tree.is_empty());
        /// ```
        pub fn new() -> Self {
            Self {
                fixed_head: None,
                count: 0,
                _marker: PhantomData,
            }
        }

        /// Returns the number of values stored in the tree.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.insert(10);
        /// tree.insert(20);
        ///
        /// assert_eq!(tree.len(), 2);
        /// ```
        pub fn len(&self) -> usize {
            self.count
        }

        /// Returns `true` if the tree contains no values.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::<i32>::new();
        /// assert!(tree.is_empty());
        ///
        /// tree.insert(10);
        /// assert!(!tree.is_empty());
        /// ```
        pub fn is_empty(&self) -> bool {
            self.count == 0
        }

        /// Removes all values from the tree.
        ///
        /// After calling `clear`, the tree is empty and can be reused.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([1, 2, 3]);
        ///
        /// tree.clear();
        ///
        /// assert!(tree.is_empty());
        /// assert_eq!(tree.len(), 0);
        /// ```
        pub fn clear(&mut self) {
            unsafe {
                if let Some(fixed_head) = self.fixed_head {
                    let root = (*fixed_head.as_ptr()).left;

                    (*fixed_head.as_ptr()).left = None;

                    self.remove_tree(root);
                }

                debug_assert_eq!(self.count, 0);
            }
        }

        /// Returns the smallest value in the tree.
        ///
        /// Returns `None` if the tree is empty.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([8, 3, 10, 1]);
        ///
        /// assert_eq!(tree.first(), Some(&1));
        /// ```
        pub fn first(&self) -> Option<&T> {
            self.minimum()
        }

        /// Returns the largest value in the tree.
        ///
        /// Returns `None` if the tree is empty.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([8, 3, 10, 14]);
        ///
        /// assert_eq!(tree.last(), Some(&14));
        /// ```
        pub fn last(&self) -> Option<&T> {
            self.maximum()
        }

        fn minimum(&self) -> Option<&T> {
            unsafe {
                let root = self.get_root()?;
                let node = self.find_min(root);
                Some(&node.as_ref().value)
            }
        }

        fn maximum(&self) -> Option<&T> {
            unsafe {
                let root = self.get_root()?;
                let node = self.find_max(root);

                Some(&node.as_ref().value)
            }
        }

        /// Returns the height of the tree.
        ///
        /// An empty tree has height `0`.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// assert_eq!(tree.height(), 0);
        ///
        /// tree.insert(10);
        /// assert_eq!(tree.height(), 1);
        /// ```
        pub fn height(&self) -> usize {
            unsafe fn height_from<T>(node: Link<T>) -> usize {
                unsafe {
                    match node {
                        None => 0,

                        Some(node) => {
                            let left_height = height_from(node.as_ref().left);
                            let right_height = height_from(node.as_ref().right);

                            1 + left_height.max(right_height)
                        }
                    }
                }
            }

            unsafe { height_from(self.get_root()) }
        }

        /// Returns `true` if the tree contains `value`.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([1, 3, 5]);
        ///
        /// assert!(tree.contains(&3));
        /// assert!(!tree.contains(&4));
        /// ```
        pub fn contains(&self, value: &T) -> bool {
            !find_node(self.get_root(), value).is_none()
        }

        /// Inserts a value into the tree.
        ///
        /// Returns `true` if the value was inserted.
        ///
        /// Returns `false` if the value already exists.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        ///
        /// assert!(tree.insert(10));
        /// assert!(!tree.insert(10));
        /// ```
        pub fn insert(&mut self, value: T) -> bool {
            unsafe {
                if let Some(fixed_head) = self.fixed_head {
                    if (*fixed_head.as_ptr()).left.is_none() {
                        (*fixed_head.as_ptr()).left = Node::new_black(value);
                        self.count += 1;
                        return true;
                    }

                    let parent = self.find_put_parent_candidate(self.get_root(), &value);

                    if let Some(parent) = parent {
                        if self.attach_node(parent, value) {
                            self.put_balancing(parent);
                        } else {
                            return false;
                        }
                    } else {
                        return false;
                    }
                } else {
                    self.fixed_head = Node::new_fixed_head(value);
                }

                self.count += 1;
                true
            }
        }

        /// Removes a value from the tree.
        ///
        /// Returns `true` if the value existed and was removed.
        ///
        /// Use [`RedBlackTree::take`] when ownership of the removed value is needed.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.insert(10);
        ///
        /// assert!(tree.remove(&10));
        /// assert!(!tree.contains(&10));
        /// assert!(!tree.remove(&10));
        /// ```
        pub fn remove(&mut self, value: &T) -> bool {
            self.take(value).is_some()
        }

        /// Inserts `value` into the tree, replacing an existing equal value.
        ///
        /// If the tree already contains a value that compares equal to `value`,
        /// the existing value is replaced and returned.
        ///
        /// If no equal value exists, `value` is inserted and `None` is returned.
        ///
        /// This is especially useful for custom types whose [`Ord`] implementation
        /// compares only a key field.
        ///
        /// # Examples
        ///
        /// ```
        /// use std::cmp::Ordering;
        /// use rbtree_extended::RedBlackTree;
        ///
        /// #[derive(Debug, Default)]
        /// struct User {
        ///     id: u32,
        ///     name: String,
        /// }
        ///
        /// impl PartialEq for User {
        ///     fn eq(&self, other: &Self) -> bool {
        ///         self.id == other.id
        ///     }
        /// }
        ///
        /// impl Eq for User {}
        ///
        /// impl PartialOrd for User {
        ///     fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        ///         Some(self.cmp(other))
        ///     }
        /// }
        ///
        /// impl Ord for User {
        ///     fn cmp(&self, other: &Self) -> Ordering {
        ///         self.id.cmp(&other.id)
        ///     }
        /// }
        ///
        /// let mut users = RedBlackTree::new();
        ///
        /// users.insert(User {
        ///     id: 1,
        ///     name: "Alice".into(),
        /// });
        ///
        /// let old = users.replace(User {
        ///     id: 1,
        ///     name: "Bob".into(),
        /// });
        ///
        /// assert_eq!(old.unwrap().name, "Alice");
        /// assert_eq!(users.first().unwrap().name, "Bob");
        /// ```
        pub fn replace(&mut self, value: T) -> Option<T> {
            unsafe {
                if let Some(mut node) = find_node(self.get_root(), &value) {
                    return Some(std::mem::replace(&mut node.as_mut().value, value));
                }
            }

            self.insert(value);

            None
        }

        unsafe fn take_node(&mut self, mut node: NonNull<Node<T>>) -> Option<T> {
            unsafe {
                // Save the original value before the internal removal algorithm
                // starts swapping values between nodes.
                let removed_value = std::mem::take(&mut node.as_mut().value);

                if !self.remove_node(node) {
                    return None;
                }

                self.count -= 1;

                Some(removed_value)
            }
        }

        /// Removes and returns the value equal to `value`.
        ///
        /// Returns `None` if the value is not present in the tree.
        ///
        /// Unlike [`RedBlackTree::remove`], this method gives ownership of the
        /// removed value back to the caller.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([10, 5, 20]);
        ///
        /// assert_eq!(tree.take(&10), Some(10));
        /// assert!(!tree.contains(&10));
        /// assert_eq!(tree.take(&100), None);
        /// ```
        pub fn take(&mut self, value: &T) -> Option<T> {
            if self.is_empty() {
                return None;
            }

            unsafe {
                let node = find_node(self.get_root(), value)?;
                self.take_node(node)
            }
        }

        /// Retains only the values specified by the predicate.
        ///
        /// In other words, removes every value for which `f(&value)` returns `false`.
        ///
        /// The predicate receives a shared reference to each stored value.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([1, 2, 3, 4, 5, 6]);
        ///
        /// tree.retain(|value| value % 2 == 0);
        ///
        /// assert_eq!(
        ///     tree.iter().copied().collect::<Vec<_>>(),
        ///     vec![2, 4, 6]
        /// );
        /// ```
        ///
        /// Retaining no values empties the tree:
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([1, 2, 3]);
        ///
        /// tree.retain(|_| false);
        ///
        /// assert!(tree.is_empty());
        /// ```
        pub fn retain<F>(&mut self, mut f: F)
        where
            F: FnMut(&T) -> bool,
        {
            let mut retained = Self::new();

            while let Some(value) = self.pop_first() {
                if f(&value) {
                    retained.insert(value);
                }
            }

            *self = retained;
        }

        /// Removes and returns the smallest value in the tree.
        ///
        /// Returns `None` if the tree is empty.
        ///
        /// This operation is useful when values need to be processed in
        /// ascending order.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([8, 3, 10, 1, 6]);
        ///
        /// assert_eq!(tree.pop_first(), Some(1));
        /// assert_eq!(tree.pop_first(), Some(3));
        /// assert_eq!(tree.len(), 3);
        /// ```
        pub fn pop_first(&mut self) -> Option<T> {
            unsafe {
                let root = self.get_root()?;
                let node = self.find_min(root);

                self.take_node(node)
            }
        }

        /// Removes and returns the largest value in the tree.
        ///
        /// Returns `None` if the tree is empty.
        ///
        /// This operation can be used to implement a priority queue where the
        /// greatest value represents the highest priority.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([8, 3, 10, 1, 6]);
        ///
        /// assert_eq!(tree.pop_last(), Some(10));
        /// assert_eq!(tree.pop_last(), Some(8));
        /// assert_eq!(tree.len(), 3);
        /// ```
        pub fn pop_last(&mut self) -> Option<T> {
            unsafe {
                let root = self.get_root()?;
                let node = self.find_max(root);

                self.take_node(node)
            }
        }

        /// Returns a reference to the stored value equal to `value`.
        ///
        /// Returns `None` if no matching value exists.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([1, 3, 5]);
        ///
        /// assert_eq!(tree.get(&3), Some(&3));
        /// assert_eq!(tree.get(&4), None);
        /// ```
        pub fn get(&self, value: &T) -> Option<&T> {
            unsafe {
                let node = find_node(self.get_root(), value)?;
                Some(&node.as_ref().value)
            }
        }

        /// Returns the next greater value in sorted order.
        ///
        /// Returns `None` if `value` is not present or if it is the largest value.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([1, 3, 5, 7]);
        ///
        /// assert_eq!(tree.successor(&3), Some(&5));
        /// assert_eq!(tree.successor(&7), None);
        /// ```
        pub fn successor(&self, value: &T) -> Option<&T> {
            unsafe {
                let node = find_node(self.get_root(), value)?;

                // Case 1:
                // there is a right subtree - successor = minimum element on the right
                if let Some(right) = node.as_ref().right {
                    let successor = self.find_min(right);
                    return Some(&successor.as_ref().value);
                }

                // Case 2:
                // there is no right subtree
                // Move up while the current node is a right child
                let mut current = node;
                let mut parent = current.as_ref().parent;

                while let Some(p) = parent {
                    if let Some(left) = p.as_ref().left
                        && std::ptr::eq(left.as_ptr(), current.as_ptr())
                    {
                        return Some(&p.as_ref().value);
                    }

                    current = p;
                    parent = p.as_ref().parent;
                }

                None
            }
        }

        /// Returns the previous smaller value in sorted order.
        ///
        /// Returns `None` if `value` is not present or if it is the smallest value.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([1, 3, 5, 7]);
        ///
        /// assert_eq!(tree.predecessor(&5), Some(&3));
        /// assert_eq!(tree.predecessor(&1), None);
        /// ```
        pub fn predecessor(&self, value: &T) -> Option<&T> {
            unsafe {
                let node = find_node(self.get_root(), value)?;

                // Case 1:
                // there is a left subtree - predecessor = maximum element on the left
                if let Some(left) = node.as_ref().left {
                    let predecessor = self.find_max(left);
                    return Some(&predecessor.as_ref().value);
                }

                // Case 2:
                // there is no left subtree
                // Move up while the current node is a left child
                let mut current = node;
                let mut parent = current.as_ref().parent;

                while let Some(p) = parent {
                    if let Some(right) = p.as_ref().right
                        && std::ptr::eq(right.as_ptr(), current.as_ptr())
                    {
                        return Some(&p.as_ref().value);
                    }

                    current = p;
                    parent = p.as_ref().parent;
                }

                None
            }
        }

        /// Returns the first value greater than or equal to `value`.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([1, 3, 6, 8]);
        ///
        /// assert_eq!(tree.lower_bound(&5), Some(&6));
        /// assert_eq!(tree.lower_bound(&6), Some(&6));
        /// ```
        pub fn lower_bound(&self, value: &T) -> Option<&T> {
            unsafe {
                let mut current = self.get_root();
                let mut candidate: Link<T> = None;

                while let Some(node) = current {
                    match node.as_ref().value.cmp(value) {
                        Ordering::Less => {
                            current = node.as_ref().right;
                        }

                        Ordering::Equal => {
                            return Some(&node.as_ref().value);
                        }

                        Ordering::Greater => {
                            candidate = Some(node);
                            current = node.as_ref().left;
                        }
                    }
                }

                candidate.map(|node| &node.as_ref().value)
            }
        }

        /// Returns the first value strictly greater than `value`.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([1, 3, 6, 8]);
        ///
        /// assert_eq!(tree.upper_bound(&6), Some(&8));
        /// assert_eq!(tree.upper_bound(&8), None);
        /// ```
        pub fn upper_bound(&self, value: &T) -> Option<&T> {
            unsafe {
                let mut current = self.get_root();
                let mut candidate: Link<T> = None;

                while let Some(node) = current {
                    match node.as_ref().value.cmp(value) {
                        Ordering::Less | Ordering::Equal => {
                            current = node.as_ref().right;
                        }
                        Ordering::Greater => {
                            candidate = Some(node);
                            current = node.as_ref().left;
                        }
                    }
                }

                candidate.map(|node| &node.as_ref().value)
            }
        }

        /// Returns an iterator over values in the inclusive range `[min, max]`.
        ///
        /// Values are yielded in ascending order.
        ///
        /// The iterator is lazy: values are produced only as they are requested,
        /// rather than being collected into an intermediate `Vec`.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([1, 3, 5, 7, 9, 11]);
        ///
        /// let values: Vec<_> = tree
        ///     .range(&3, &9)
        ///     .copied()
        ///     .collect();
        ///
        /// assert_eq!(values, vec![3, 5, 7, 9]);
        /// ```
        pub fn range(&self, min: &T, max: &T) -> Range<'_, T> {
            Range::new(self.get_root(), min, max)
        }

        /// Returns the next value in an in-order (`LNR`) traversal.
        ///
        /// For a binary search tree, in-order traversal visits values in ascending order.
        ///
        /// Returns `None` if `value` is not present or has no successor in this traversal.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([4, 2, 6, 1, 3, 5, 7]);
        ///
        /// assert_eq!(tree.successor_dfs_in_order(4), Some(&5));
        /// ```
        pub fn successor_dfs_in_order(&self, value: T) -> Option<&T> {
            unsafe {
                let node = find_node(self.get_root(), &value);
                if let Some(n) = node
                    && let Some(nodesucc) = successor_of_node_in_order(n)
                {
                    return Some(&nodesucc.as_ref().value);
                }
                None
            }
        }

        /// Returns the next value in reverse in-order (`RNL`) traversal.
        ///
        /// For a binary search tree, reverse in-order traversal visits values in
        /// descending order.
        ///
        /// Returns `None` if `value` is not present or has no successor in this traversal.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([4, 2, 6, 1, 3, 5, 7]);
        ///
        /// assert_eq!(tree.successor_dfs_reverse_in_order(6), Some(&5));
        /// ```
        pub fn successor_dfs_reverse_in_order(&self, value: T) -> Option<&T> {
            unsafe {
                if let Some(node) = find_node(self.get_root(), &value)
                    && let Some(next) = successor_of_node_reverse_in_order(node)
                {
                    return Some(&next.as_ref().value);
                }
                None
            }
        }

        /// Returns the next value in post-order (`LRN`) traversal.
        ///
        /// Post-order visits the left subtree, then the right subtree,
        /// and finally the current node.
        ///
        /// Returns `None` if `value` is not present or has no successor in this traversal.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([4, 2, 6, 1, 3, 5, 7]);
        ///
        /// // Post-order: 1, 3, 2, 5, 7, 6, 4
        /// assert_eq!(tree.successor_dfs_post_order(3), Some(&2));
        /// assert_eq!(tree.successor_dfs_post_order(2), Some(&5));
        /// assert_eq!(tree.successor_dfs_post_order(4), None);
        /// ```
        pub fn successor_dfs_post_order(&self, value: T) -> Option<&T> {
            unsafe {
                if let Some(n) = find_node(self.get_root(), &value)
                    && let Some(nodesucc) = successor_of_node_post_order(n)
                {
                    return Some(&nodesucc.as_ref().value);
                }
                None
            }
        }

        /// Returns the next value in pre-order (`NLR`) traversal.
        ///
        /// Pre-order visits the current node first, followed by the left and right
        /// subtrees.
        ///
        /// Returns `None` if `value` is not present or has no successor in this traversal.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([4, 2, 6, 1, 3, 5, 7]);
        ///
        /// let first = *tree.iter_preorder().next().unwrap();
        /// assert_eq!(tree.successor_dfs_pre_order(first), tree.iter_preorder().nth(1));
        /// ```
        pub fn successor_dfs_pre_order(&self, value: T) -> Option<&T> {
            unsafe {
                if let Some(n) = find_node(self.get_root(), &value)
                    && let Some(nodesucc) = successor_of_node_pre_order(n)
                {
                    return Some(&nodesucc.as_ref().value);
                }
                None
            }
        }

        fn get_root(&self) -> Link<T> {
            if let Some(fixed_head) = self.fixed_head {
                unsafe { (*fixed_head.as_ptr()).left }
            } else {
                None
            }
        }

        unsafe fn operation_remove(&self, node_x: &NonNull<Node<T>>) -> OperationRemove {
            unsafe {
                if node_x.as_ref().is_red
                    && node_x.as_ref().left.is_none()
                    && node_x.as_ref().right.is_none()
                {
                    return OperationRemove::RedLeaf;
                }
                if node_x.as_ref().is_red
                    && node_x.as_ref().left.is_some()
                    && node_x.as_ref().right.is_some()
                {
                    return OperationRemove::NodeWithChildren;
                }
                if !node_x.as_ref().is_red {
                    if node_x.as_ref().left.is_some() && node_x.as_ref().right.is_some() {
                        return OperationRemove::NodeWithChildren;
                    } else if node_x.as_ref().left.is_some() && node_x.as_ref().right.is_none() {
                        if let Some(left) = node_x.as_ref().left
                            && left.as_ref().is_red
                            && left.as_ref().left.is_none()
                            && left.as_ref().right.is_none()
                        {
                            return OperationRemove::BlackNodeWithRedLeaf;
                        }
                    } else if node_x.as_ref().left.is_none() && node_x.as_ref().right.is_none() {
                        return OperationRemove::BlackLeaf;
                    }
                }
                panic!();
            }
        }

        unsafe fn operation_remove_black_leaf(
            &self,
            node_x: &NonNull<Node<T>>,
        ) -> OperationRemoveBlackLeaf {
            unsafe {
                if let Some(node_a) = node_x.as_ref().parent {
                    if node_a.as_ref().is_red {
                        if let Some(node_b) = node_a.as_ref().left
                            && !std::ptr::eq(node_b.as_ptr(), node_x.as_ptr())
                            && !node_b.as_ref().is_red
                        {
                            if let Some(node_c) = node_b.as_ref().left
                                && node_c.as_ref().is_red
                            {
                                return OperationRemoveBlackLeaf::LeftRedABlackBRedCleaf;
                                // 2.1.1.1
                            }

                            // sibling B is black and its left child is either absent or also black
                            return OperationRemoveBlackLeaf::LeftRedABlackBleaf;
                            // 2.1.2.1
                        }

                        if let Some(node_b) = node_a.as_ref().right
                            && !std::ptr::eq(node_b.as_ptr(), node_x.as_ptr())
                            && !node_b.as_ref().is_red
                        {
                            if let Some(node_c) = node_b.as_ref().left
                                && node_c.as_ref().is_red
                            {
                                return OperationRemoveBlackLeaf::RightRedABlackBRedCleaf;
                                // 2.1.1.2
                            }

                            // sibling B is black and its left child is either absent or also black
                            return OperationRemoveBlackLeaf::RightRedABlackBleaf;
                            // 2.1.2.2
                        }
                    } else {
                        if let Some(node_b) = node_a.as_ref().left
                            && !std::ptr::eq(node_b.as_ptr(), node_x.as_ptr())
                        {
                            if node_b.as_ref().is_red && node_b.as_ref().right.is_some() {
                                let node_c = node_b.as_ref().right.unwrap();
                                if !node_c.as_ref().is_red {
                                    if node_c.as_ref().left.is_some()
                                        && let Some(node_d) = node_c.as_ref().left
                                        && node_d.as_ref().is_red
                                    {
                                        return OperationRemoveBlackLeaf::BlackARedBWithBlackChildrenRightHaveRedLeaf;
                                        // 2.2.1
                                    }
                                    return OperationRemoveBlackLeaf::BlackARedBWithBlackChildrenLeaf;
                                    // 2.2.2
                                }
                            }
                            if !node_b.as_ref().is_red
                                && node_b.as_ref().left.is_some()
                                && let Some(node_d) = node_b.as_ref().left
                                && node_d.as_ref().is_red
                            {
                                return OperationRemoveBlackLeaf::BlackALeftBlackBRedDleaf;
                                // 2.3.1.1
                            }
                            if !node_b.as_ref().is_red {
                                return OperationRemoveBlackLeaf::BlackALeftBlackBleaf;
                                // 2.3.2.1
                            }
                        }
                        if let Some(node_b) = node_a.as_ref().right
                            && !std::ptr::eq(node_b.as_ptr(), node_x.as_ptr())
                        {
                            if !node_b.as_ref().is_red
                                && node_b.as_ref().left.is_some()
                                && let Some(node_d) = node_b.as_ref().left
                                && node_d.as_ref().is_red
                            {
                                return OperationRemoveBlackLeaf::BlackARightBlackBRedDleaf;
                                // 2.3.1.2
                            }
                            if !node_b.as_ref().is_red {
                                return OperationRemoveBlackLeaf::BlackARightBlackBleaf;
                                // 2.3.2.2
                            }
                        }
                    }
                } else {
                    return OperationRemoveBlackLeaf::Root;
                }
                OperationRemoveBlackLeaf::Unimplemented
            }
        }

        unsafe fn remove_black_leaf(&mut self, node_x: NonNull<Node<T>>) -> bool {
            unsafe {
                let mut next = node_x;
                let mut removed = false;
                loop {
                    match self.operation_remove_black_leaf(&next) {
                        OperationRemoveBlackLeaf::LeftRedABlackBRedCleaf => {
                            self.remove_black_leaf_2_1_1_1_balancing(&next);
                            if !removed {
                                removed = self.remove_leaf(node_x);
                            }
                            break;
                        }
                        OperationRemoveBlackLeaf::RightRedABlackBRedCleaf => {
                            self.remove_black_leaf_2_1_1_2_balancing(&next);
                            if !removed {
                                removed = self.remove_leaf(node_x);
                            }
                            break;
                        }
                        OperationRemoveBlackLeaf::LeftRedABlackBleaf => {
                            self.remove_black_leaf_2_1_2_1_balancing(&next);
                            if !removed {
                                removed = self.remove_leaf(node_x);
                            }
                            break;
                        }
                        OperationRemoveBlackLeaf::RightRedABlackBleaf => {
                            self.remove_black_leaf_2_1_2_2_balancing(&next);
                            if !removed {
                                removed = self.remove_leaf(node_x);
                            }
                            break;
                        }
                        OperationRemoveBlackLeaf::BlackARedBWithBlackChildrenRightHaveRedLeaf => {
                            self.remove_black_leaf_2_2_1_balancing(&next);
                            if !removed {
                                removed = self.remove_leaf(node_x);
                            }
                            break;
                        }
                        OperationRemoveBlackLeaf::BlackARedBWithBlackChildrenLeaf => {
                            self.remove_black_leaf_2_2_2_balancing(&next);
                            if !removed {
                                removed = self.remove_leaf(node_x);
                            }
                            break;
                        }
                        OperationRemoveBlackLeaf::BlackALeftBlackBRedDleaf => {
                            self.remove_black_leaf_2_3_1_1_balancing(&next);
                            if !removed {
                                removed = self.remove_leaf(node_x);
                            }
                            break;
                        }
                        OperationRemoveBlackLeaf::BlackARightBlackBRedDleaf => {
                            self.remove_black_leaf_2_3_1_2_balancing(&next);
                            if !removed {
                                removed = self.remove_leaf(node_x);
                            }
                            break;
                        }
                        OperationRemoveBlackLeaf::BlackALeftBlackBleaf => {
                            next = self.remove_black_leaf_2_3_2_1_balancing(&next);
                            if !removed {
                                removed = self.remove_leaf(node_x);
                            }
                        }
                        OperationRemoveBlackLeaf::BlackARightBlackBleaf => {
                            next = self.remove_black_leaf_2_3_2_2_balancing(&next);
                            if !removed {
                                removed = self.remove_leaf(node_x);
                            }
                        }
                        OperationRemoveBlackLeaf::Root => {
                            if !removed {
                                // We get here when the node_x being deleted is root
                                if let Some(fixed_head) = self.fixed_head {
                                    (*fixed_head.as_ptr()).left = None;
                                }
                                let _ = Box::from_raw(node_x.as_ptr());
                                removed = true;
                            }
                            break;
                        }
                        OperationRemoveBlackLeaf::Unimplemented => {
                            panic!("unimplemented black leaf removal case");
                        }
                    }
                }
                removed
            }
        }

        /// 2.1.1.1 remove black X
        ///
        /// ```text
        ///             P            P
        ///            //           //
        ///            A            B
        ///           / \          / \
        ///          B   X   =>   C   A
        ///         //\              /
        ///        C   D            D
        /// ```
        unsafe fn remove_black_leaf_2_1_1_1_balancing(&mut self, node_x: &NonNull<Node<T>>) {
            unsafe {
                let node_a = (*node_x.as_ptr()).parent.unwrap();
                let node_b = (*node_a.as_ptr()).left.unwrap();
                let node_d = (*node_b.as_ptr()).right;
                (*node_b.as_ptr()).parent = (*node_a.as_ptr()).parent;
                if let Some(ref mut parent) = (*node_b.as_ptr()).parent {
                    (*parent.as_ptr()).left = Some(node_b);
                }
                (*node_a.as_ptr()).left = node_d;
                if let Some(n_d) = node_d {
                    (*n_d.as_ptr()).parent = Some(node_a);
                }
                (*node_a.as_ptr()).is_red = false;
                (*node_b.as_ptr()).right = Some(node_a);
                (*node_a.as_ptr()).parent = Some(node_b);
                (*node_b.as_ptr()).is_red = true;
                if let Some(node_c) = (*node_b.as_ptr()).left {
                    (*node_c.as_ptr()).is_red = false;
                }
            }
        }

        /// 2.1.1.2 remove black X
        ///
        /// ```text
        ///             P              P
        ///            //             //
        ///           A               C
        ///          / \            /   \
        ///         X   B   =>     A     B
        ///            //           \   /
        ///            C             E D
        ///           / \
        ///          E   D
        /// ```
        unsafe fn remove_black_leaf_2_1_1_2_balancing(&mut self, node_x: &NonNull<Node<T>>) {
            unsafe {
                let node_a = (*node_x.as_ptr()).parent.unwrap();
                (*node_a.as_ptr()).is_red = false;
                let parent: NonNull<Node<T>> = (*node_a.as_ptr()).parent.unwrap();
                let node_b = (*node_a.as_ptr()).right.unwrap();
                let node_c = (*node_b.as_ptr()).left.unwrap();
                let node_e = (*node_c.as_ptr()).left;
                let node_d = (*node_c.as_ptr()).right;
                (*parent.as_ptr()).left = Some(node_c);
                (*node_c.as_ptr()).parent = Some(parent);
                (*node_b.as_ptr()).left = node_d;
                if let Some(n_d) = node_d {
                    (*n_d.as_ptr()).parent = Some(node_b);
                }
                (*node_c.as_ptr()).right = Some(node_b);
                (*node_b.as_ptr()).parent = Some(node_c);
                (*node_c.as_ptr()).left = Some(node_a);
                (*node_a.as_ptr()).parent = Some(node_c);
                (*node_a.as_ptr()).right = node_e;
                if let Some(n_e) = node_e {
                    (*n_e.as_ptr()).parent = Some(node_a);
                }
            }
        }

        /// 2.1.2.1 remove black X
        ///
        /// ```text
        ///              P            P
        ///             //           /
        ///            A            A
        ///           / \          //
        ///          B   X   =>   B
        ///
        /// ```
        unsafe fn remove_black_leaf_2_1_2_1_balancing(&mut self, node_x: &NonNull<Node<T>>) {
            unsafe {
                let node_a = (*node_x.as_ptr()).parent.unwrap();
                (*node_a.as_ptr()).is_red = false;
                if let Some(node_b) = (*node_a.as_ptr()).left {
                    (*node_b.as_ptr()).is_red = true;
                }
            }
        }

        /// 2.1.2.2 remove black X
        ///
        /// ```text
        ///             P            P
        ///            //           /
        ///            A     =>     B
        ///           / \          //\
        ///          X   B        A   D
        ///             / \        \
        ///            C   D        C
        /// ```
        unsafe fn remove_black_leaf_2_1_2_2_balancing(&mut self, node_x: &NonNull<Node<T>>) {
            unsafe {
                let node_a = (*node_x.as_ptr()).parent.unwrap();
                let node_b = (*node_a.as_ptr()).right.unwrap();
                let node_c = (*node_b.as_ptr()).left;
                let node_d = (*node_b.as_ptr()).right;
                let parent = (*node_a.as_ptr()).parent.unwrap();
                if let Some(left) = (*parent.as_ptr()).left {
                    if std::ptr::eq(node_a.as_ptr(), left.as_ptr()) {
                        (*parent.as_ptr()).left = Some(node_b);
                    } else {
                        (*parent.as_ptr()).right = Some(node_b);
                    }
                } else {
                    (*parent.as_ptr()).right = Some(node_b);
                }
                (*node_b.as_ptr()).parent = Some(parent);
                (*node_b.as_ptr()).left = Some(node_a);
                (*node_b.as_ptr()).right = node_d;
                if let Some(n_d) = node_d {
                    (*n_d.as_ptr()).parent = Some(node_b);
                }
                (*node_a.as_ptr()).parent = Some(node_b);
                (*node_a.as_ptr()).right = node_c;
                if let Some(n_c) = node_c {
                    (*n_c.as_ptr()).parent = Some(node_a);
                }
            }
        }

        /// 2.2.1 remove black X
        ///
        /// ```text
        ///            A               C
        ///          // \            //  \
        ///         B    X    =>    B     A
        ///          \               \   /
        ///           C               D E
        ///           //\
        ///          D   E
        /// ```
        unsafe fn remove_black_leaf_2_2_1_balancing(&mut self, node_x: &NonNull<Node<T>>) {
            unsafe {
                let n_a = node_x.as_ref().parent.unwrap();
                if n_a.as_ref().parent.is_some() {
                    let parent = (*n_a.as_ptr()).parent.unwrap();
                    let mut node_a_from_left = false;
                    if let Some(ref mut node_a) = (*parent.as_ptr()).left
                        && std::ptr::eq(node_a.as_ptr(), n_a.as_ptr())
                    {
                        node_a_from_left = true;
                    }
                    let node_a = if node_a_from_left {
                        (*parent.as_ptr()).left.unwrap()
                    } else {
                        (*parent.as_ptr()).right.unwrap()
                    };
                    let node_b = (*node_a.as_ptr()).left.unwrap();
                    let node_c = (*node_b.as_ptr()).right.unwrap();
                    let node_e = (*node_c.as_ptr()).right;
                    let node_d = (*node_c.as_ptr()).left.unwrap();
                    (*node_b.as_ptr()).right = Some(node_d);
                    (*node_b.as_ptr()).parent = Some(node_c);
                    (*node_d.as_ptr()).parent = Some(node_b);
                    (*node_a.as_ptr()).parent = Some(node_c);
                    (*node_a.as_ptr()).left = node_e;
                    if let Some(n_e) = node_e {
                        (*n_e.as_ptr()).parent = Some(node_a);
                    }
                    (*node_d.as_ptr()).is_red = false;
                    (*node_c.as_ptr()).left = Some(node_b);
                    (*node_c.as_ptr()).right = Some(node_a);
                    (*node_c.as_ptr()).parent = Some(parent);
                    if node_a_from_left {
                        (*parent.as_ptr()).left = Some(node_c);
                    } else {
                        (*parent.as_ptr()).right = Some(node_c);
                    }
                } else {
                    // node_a is root
                    if let Some(fixed_head) = self.fixed_head {
                        let node_a = (*fixed_head.as_ptr()).left.unwrap();
                        let node_b = (*node_a.as_ptr()).left.unwrap();
                        let node_c = (*node_b.as_ptr()).right.unwrap();
                        let node_e = (*node_c.as_ptr()).right;
                        let node_d = (*node_c.as_ptr()).left.unwrap();
                        (*node_b.as_ptr()).right = Some(node_d);
                        (*node_b.as_ptr()).parent = Some(node_c);
                        (*node_d.as_ptr()).parent = Some(node_b);
                        (*node_a.as_ptr()).parent = Some(node_c);
                        (*node_a.as_ptr()).left = node_e;
                        if let Some(n_e) = node_e {
                            (*n_e.as_ptr()).parent = Some(node_a);
                        }
                        (*node_d.as_ptr()).is_red = false;
                        (*node_c.as_ptr()).left = Some(node_b);
                        (*node_c.as_ptr()).right = Some(node_a);
                        (*node_c.as_ptr()).parent = None;
                        (*fixed_head.as_ptr()).left = Some(node_c);
                    }
                }
            }
        }

        /// 2.2.2 remove black X
        ///
        /// ```text
        ///    A            B
        ///  // \            \
        ///  B    X   =>       A
        ///  \               //
        ///   C             C
        /// ```
        unsafe fn remove_black_leaf_2_2_2_balancing(&mut self, node_x: &NonNull<Node<T>>) {
            unsafe {
                let n_a = node_x.as_ref().parent.unwrap();
                if n_a.as_ref().parent.is_some() {
                    let parent = (*n_a.as_ptr()).parent.unwrap();
                    let mut node_a_from_left = false;
                    if let Some(ref mut node_a) = (*parent.as_ptr()).left
                        && std::ptr::eq(node_a.as_ptr(), n_a.as_ptr())
                    {
                        node_a_from_left = true;
                    }
                    let node_a = if node_a_from_left {
                        (*parent.as_ptr()).left.unwrap()
                    } else {
                        (*parent.as_ptr()).right.unwrap()
                    };
                    let node_b = (*node_a.as_ptr()).left.unwrap();
                    (*node_b.as_ptr()).is_red = false;
                    (*node_b.as_ptr()).parent = Some(parent);
                    let node_c = (*node_b.as_ptr()).right.unwrap();
                    (*node_c.as_ptr()).is_red = true;
                    (*node_b.as_ptr()).right = Some(node_a);
                    (*node_a.as_ptr()).left = Some(node_c);
                    (*node_c.as_ptr()).parent = Some(node_a);
                    (*node_a.as_ptr()).parent = Some(node_b);
                    if node_a_from_left {
                        (*parent.as_ptr()).left = Some(node_b);
                    } else {
                        (*parent.as_ptr()).right = Some(node_b);
                    }
                } else {
                    // node_a is root
                    if let Some(fixed_head) = self.fixed_head {
                        let node_a = (*fixed_head.as_ptr()).left.unwrap();
                        let node_b = (*node_a.as_ptr()).left.unwrap();
                        (*node_b.as_ptr()).is_red = false;
                        (*node_b.as_ptr()).parent = None;
                        let node_c = (*node_b.as_ptr()).right.unwrap();
                        (*node_c.as_ptr()).is_red = true;
                        (*node_b.as_ptr()).right = Some(node_a);
                        (*node_a.as_ptr()).left = Some(node_c);
                        (*node_c.as_ptr()).parent = Some(node_a);
                        (*node_a.as_ptr()).parent = Some(node_b);
                        (*fixed_head.as_ptr()).left = Some(node_b);
                    }
                }
            }
        }

        /// 2.3.1.1 remove black X
        ///
        /// ```text
        ///      A           B
        ///     / \         / \
        ///    B   X  =>   D   A
        ///   // \            /
        ///  D    C          C
        /// ```
        unsafe fn remove_black_leaf_2_3_1_1_balancing(&mut self, node_x: &NonNull<Node<T>>) {
            unsafe {
                let node_a = (*node_x.as_ptr()).parent.unwrap();
                if let Some(parent) = (*node_a.as_ptr()).parent {
                    let node_b = (*node_a.as_ptr()).left.unwrap();
                    let node_c = (*node_b.as_ptr()).right;
                    let node_d = (*node_b.as_ptr()).left.unwrap();
                    (*node_d.as_ptr()).is_red = false;
                    let mut node_a_from_left = false;
                    if let Some(p_node_a) = (*parent.as_ptr()).left
                        && std::ptr::eq(p_node_a.as_ptr(), node_a.as_ptr())
                    {
                        node_a_from_left = true;
                    }
                    (*node_b.as_ptr()).parent = Some(parent);
                    (*node_b.as_ptr()).right = Some(node_a);
                    (*node_a.as_ptr()).parent = Some(node_b);
                    (*node_a.as_ptr()).left = node_c;
                    if let Some(n_c) = node_c {
                        (*n_c.as_ptr()).parent = Some(node_a);
                    }
                    if node_a_from_left {
                        (*parent.as_ptr()).left = Some(node_b);
                    } else {
                        (*parent.as_ptr()).right = Some(node_b);
                    }
                } else {
                    // node_a is root
                    if let Some(fixed_head) = self.fixed_head {
                        let node_a = (*fixed_head.as_ptr()).left.unwrap();
                        let node_b = (*node_a.as_ptr()).left.unwrap();
                        let node_c = (*node_b.as_ptr()).right;
                        let node_d = (*node_b.as_ptr()).left.unwrap();
                        (*node_d.as_ptr()).is_red = false;
                        let node_b = (*node_a.as_ptr()).left.unwrap();
                        (*node_b.as_ptr()).parent = None;
                        (*node_b.as_ptr()).right = Some(node_a);
                        (*node_a.as_ptr()).parent = Some(node_b);
                        (*node_a.as_ptr()).left = node_c;
                        if let Some(n_c) = node_c {
                            (*n_c.as_ptr()).parent = Some(node_a);
                        }
                        (*fixed_head.as_ptr()).left = Some(node_b);
                    }
                }
            }
        }

        /// 2.3.1.2 remove black X
        ///
        /// ```text
        ///
        ///      A            D
        ///     / \         /   \
        ///    X   B  =>   A     B
        ///       //        \   /
        ///       D          C E
        ///      / \
        ///     C   E
        /// ```
        unsafe fn remove_black_leaf_2_3_1_2_balancing(&mut self, node_x: &NonNull<Node<T>>) {
            unsafe {
                let node_a = (*node_x.as_ptr()).parent.unwrap();
                if let Some(parent) = (*node_a.as_ptr()).parent {
                    let node_b = (*node_a.as_ptr()).right.unwrap();
                    let node_d = (*node_b.as_ptr()).left.unwrap();
                    let node_c = (*node_d.as_ptr()).left;
                    let node_e = (*node_d.as_ptr()).right;
                    (*node_d.as_ptr()).is_red = false;
                    let mut node_a_from_left = false;
                    if let Some(p_node_a) = (*parent.as_ptr()).left
                        && std::ptr::eq(p_node_a.as_ptr(), node_a.as_ptr())
                    {
                        node_a_from_left = true;
                    }
                    (*node_d.as_ptr()).parent = Some(parent);
                    (*node_d.as_ptr()).left = Some(node_a);
                    (*node_d.as_ptr()).right = Some(node_b);
                    (*node_a.as_ptr()).parent = Some(node_d);
                    (*node_b.as_ptr()).parent = Some(node_d);
                    (*node_a.as_ptr()).right = node_c;
                    if let Some(n_c) = node_c {
                        (*n_c.as_ptr()).parent = Some(node_a);
                    }
                    (*node_b.as_ptr()).left = node_e;
                    if let Some(n_e) = node_e {
                        (*n_e.as_ptr()).parent = Some(node_b);
                    }
                    if node_a_from_left {
                        (*parent.as_ptr()).left = Some(node_d);
                    } else {
                        (*parent.as_ptr()).right = Some(node_d);
                    }
                } else {
                    // node_a is root
                    if let Some(fixed_head) = self.fixed_head {
                        let node_a = (*fixed_head.as_ptr()).left.unwrap();
                        let node_b = (*node_a.as_ptr()).right.unwrap();
                        let node_d = (*node_b.as_ptr()).left.unwrap();
                        let node_c = (*node_d.as_ptr()).left;
                        let node_e = (*node_d.as_ptr()).right;
                        (*node_d.as_ptr()).is_red = false;
                        (*node_d.as_ptr()).parent = None;
                        (*node_d.as_ptr()).left = Some(node_a);
                        (*node_d.as_ptr()).right = Some(node_b);
                        (*node_a.as_ptr()).parent = Some(node_d);
                        (*node_b.as_ptr()).parent = Some(node_d);
                        (*node_a.as_ptr()).right = node_c;
                        if let Some(n_c) = node_c {
                            (*n_c.as_ptr()).parent = Some(node_a);
                        }
                        (*node_b.as_ptr()).left = node_e;
                        if let Some(n_e) = node_e {
                            (*n_e.as_ptr()).parent = Some(node_b);
                        }
                        (*fixed_head.as_ptr()).left = Some(node_d);
                    }
                }
            }
        }

        /// 2.3.2.1 remove black X
        ///
        /// ```text
        ///            P           P
        ///            |           |
        ///            A           A
        ///           / \   =>    //   => next check node A
        ///          B   X       B
        ///
        /// ```
        unsafe fn remove_black_leaf_2_3_2_1_balancing(
            &mut self,
            node_x: &NonNull<Node<T>>,
        ) -> NonNull<Node<T>> {
            unsafe {
                let node_a = (*node_x.as_ptr()).parent.unwrap();
                let node_b = (*node_a.as_ptr()).left.unwrap();
                (*node_b.as_ptr()).is_red = true;
                node_a
            }
        }

        /// 2.3.2.2 remove black X
        ///
        /// ```text
        ///              A            B
        ///             / \   =>    // \    =>  next check node B
        ///            X   B       A    D
        ///               / \       \
        ///              C   D       C
        /// ```
        unsafe fn remove_black_leaf_2_3_2_2_balancing(
            &mut self,
            node_x: &NonNull<Node<T>>,
        ) -> NonNull<Node<T>> {
            unsafe {
                let node_a = (*node_x.as_ptr()).parent.unwrap();
                (*node_a.as_ptr()).is_red = true;
                if let Some(parent) = (*node_a.as_ptr()).parent {
                    let node_b = (*node_a.as_ptr()).right.unwrap();
                    let node_c = (*node_b.as_ptr()).left;
                    let node_d = (*node_b.as_ptr()).right;
                    let mut node_a_from_left = false;
                    if let Some(p_node_a) = (*parent.as_ptr()).left
                        && std::ptr::eq(p_node_a.as_ptr(), node_a.as_ptr())
                    {
                        node_a_from_left = true;
                    }
                    (*node_b.as_ptr()).parent = Some(parent);
                    (*node_a.as_ptr()).right = node_c;
                    if let Some(n_c) = node_c {
                        (*n_c.as_ptr()).parent = Some(node_a);
                    }
                    (*node_b.as_ptr()).right = node_d;
                    if let Some(n_d) = node_d {
                        (*n_d.as_ptr()).parent = Some(node_b);
                    }
                    (*node_b.as_ptr()).left = Some(node_a);
                    (*node_a.as_ptr()).parent = Some(node_b);
                    if node_a_from_left {
                        (*parent.as_ptr()).left = Some(node_b);
                    } else {
                        (*parent.as_ptr()).right = Some(node_b);
                    }
                    node_b
                } else {
                    // node_a is root
                    if let Some(fixed_head) = self.fixed_head {
                        let node_a = (*fixed_head.as_ptr()).left.unwrap();
                        (*node_a.as_ptr()).is_red = true;
                        let node_b = (*node_a.as_ptr()).right.unwrap();
                        let node_c = (*node_b.as_ptr()).left;
                        let node_d = (*node_b.as_ptr()).right;
                        (*node_b.as_ptr()).parent = None;
                        (*node_a.as_ptr()).right = node_c;
                        if let Some(n_c) = node_c {
                            (*n_c.as_ptr()).parent = Some(node_a);
                        }
                        (*node_b.as_ptr()).right = node_d;
                        if let Some(n_d) = node_d {
                            (*n_d.as_ptr()).parent = Some(node_b);
                        }
                        (*node_b.as_ptr()).left = Some(node_a);
                        (*node_a.as_ptr()).parent = Some(node_b);
                        (*fixed_head.as_ptr()).left = Some(node_b);
                    }
                    self.get_root().unwrap()
                }
            }
        }

        unsafe fn remove_node(&mut self, node: NonNull<Node<T>>) -> bool {
            unsafe {
                match self.operation_remove(&node) {
                    OperationRemove::RedLeaf => {
                        // option 1.0.0
                        //
                        // ```text
                        //
                        //  P
                        //  ||
                        //  X
                        //
                        // ```

                        self.remove_leaf(node)
                    }
                    OperationRemove::BlackLeaf => {
                        // option 2 black leaf
                        self.remove_black_leaf(node)
                    }
                    OperationRemove::NodeWithChildren => {
                        // option 4.0.0
                        // ```text
                        //        X
                        //     /      \
                        //    L        R
                        //   / \      / \
                        // ...  C    L
                        //          /
                        //         C
                        //        ...
                        //
                        // ```
                        /*
                            The node has two children.

                            We take the predecessor:
                            the maximal node of the left subtree.

                            We only change the values,
                            then we delete the predecessor as a regular node.
                        */

                        let predecessor = self.find_max(node.as_ref().left.unwrap());

                        std::mem::swap(
                            &mut (*node.as_ptr()).value,
                            &mut (*predecessor.as_ptr()).value,
                        );

                        self.remove_node(predecessor)
                    }
                    OperationRemove::BlackNodeWithRedLeaf => {
                        // option 3.0.0
                        // ```text
                        //  X
                        // //
                        // A
                        // ```
                        let red_left = (*node.as_ptr()).left.unwrap();
                        std::mem::swap(&mut (*node.as_ptr()).value, &mut (*red_left.as_ptr()).value);
                        self.remove_leaf(red_left)
                    }
                }
            }
        }

        unsafe fn find_max(&self, node: NonNull<Node<T>>) -> NonNull<Node<T>> {
            unsafe {
                if node.as_ref().right.is_some() {
                    self.find_max(node.as_ref().right.unwrap())
                } else {
                    node
                }
            }
        }

        unsafe fn find_min(&self, node: NonNull<Node<T>>) -> NonNull<Node<T>> {
            unsafe {
                if node.as_ref().left.is_some() {
                    self.find_min(node.as_ref().left.unwrap())
                } else {
                    node
                }
            }
        }

        unsafe fn remove_leaf(&mut self, node: NonNull<Node<T>>) -> bool {
            unsafe {
                if let Some(mut parent) = node.as_ref().parent {
                    if let Some(ref mut left) = parent.as_mut().left {
                        if std::ptr::eq(left.as_ptr(), node.as_ptr()) {
                            parent.as_mut().left = None;
                        } else {
                            parent.as_mut().right = None;
                        }
                    } else {
                        parent.as_mut().right = None;
                    }
                }
                let _ = Box::from_raw(node.as_ptr());
                true
            }
        }

        unsafe fn remove_tree(&mut self, node: Link<T>) {
            unsafe {
                if let Some(node) = node {
                    self.remove_tree(node.as_ref().left);
                    self.remove_tree(node.as_ref().right);
                    if self.remove_leaf(node) {
                        assert!(self.count > 0);
                        self.count -= 1;
                    }
                }
            }
        }

        /// Rotate left and Rotate right and Flip color
        ///
        /// ```text
        ///             |              ||
        ///             P              C
        ///           //  \          /   \
        ///          A     F        A     P
        ///         / \\      =>   / \   / \
        ///        B   C          B   E D   F
        ///            / \
        ///           E   D
        /// ```
        unsafe fn rotate_left_right_flip_color(&mut self, node_a: NonNull<Node<T>>) -> Link<T> {
            unsafe {
                let node_p = (*node_a.as_ptr()).parent.unwrap();
                if let Some(parent) = (*node_p.as_ptr()).parent {
                    let mut node_p_from_left = false;
                    if let Some(p_node_p) = (*parent.as_ptr()).left
                        && std::ptr::eq(p_node_p.as_ptr(), node_p.as_ptr())
                    {
                        node_p_from_left = true;
                    }
                    let node_p = if node_p_from_left {
                        (*parent.as_ptr()).left.unwrap()
                    } else {
                        (*parent.as_ptr()).right.unwrap()
                    };
                    (*node_a.as_ptr()).is_red = false;
                    let node_c = (*node_a.as_ptr()).right.unwrap();
                    (*node_c.as_ptr()).is_red = false;
                    let node_e = (*node_c.as_ptr()).left;
                    let node_d = (*node_c.as_ptr()).right;
                    (*node_c.as_ptr()).is_red = true;
                    (*node_c.as_ptr()).parent = Some(parent);
                    (*node_c.as_ptr()).left = Some(node_a);
                    (*node_a.as_ptr()).parent = Some(node_c);
                    (*node_c.as_ptr()).right = Some(node_p);
                    (*node_p.as_ptr()).parent = Some(node_c);
                    (*node_p.as_ptr()).left = node_d;
                    if let Some(n_d) = node_d {
                        (*n_d.as_ptr()).parent = Some(node_p);
                    }
                    (*node_a.as_ptr()).right = node_e;
                    if let Some(n_e) = node_e {
                        (*n_e.as_ptr()).parent = Some(node_a);
                    }
                    if node_p_from_left {
                        (*parent.as_ptr()).left = Some(node_c);
                    } else {
                        (*parent.as_ptr()).right = Some(node_c);
                    }
                    Some(parent)
                } else {
                    let fixed_head = self.fixed_head.unwrap();
                    let node_p = (*fixed_head.as_ptr()).left.unwrap();

                    let node_a = (*node_p.as_ptr()).left.unwrap();
                    (*node_a.as_ptr()).is_red = false;
                    let node_c = (*node_a.as_ptr()).right.unwrap();
                    (*node_c.as_ptr()).is_red = false;
                    let node_e = (*node_c.as_ptr()).left;
                    let node_d = (*node_c.as_ptr()).right;
                    (*node_c.as_ptr()).is_red = false;
                    (*node_c.as_ptr()).parent = None;
                    (*node_c.as_ptr()).left = Some(node_a);
                    (*node_a.as_ptr()).parent = Some(node_c);
                    (*node_c.as_ptr()).right = Some(node_p);
                    (*node_p.as_ptr()).parent = Some(node_c);
                    (*node_p.as_ptr()).left = node_d;
                    if let Some(n_d) = node_d {
                        (*n_d.as_ptr()).parent = Some(node_p);
                    }
                    (*node_a.as_ptr()).right = node_e;
                    if let Some(n_e) = node_e {
                        (*n_e.as_ptr()).parent = Some(node_a);
                    }
                    (*fixed_head.as_ptr()).left = Some(node_c);
                    (*fixed_head.as_ptr()).left
                }
            }
        }

        /// Rotate left without parent
        /// A is root
        ///
        /// ```text
        ///             A                  C
        ///            / \\               //\
        ///           B    C     =>      A   D
        ///               / \           / \
        ///              E   D         B   E
        ///
        /// ```
        ///
        /// Rotate left  with parent
        ///
        /// ```text
        ///             P                  P
        ///             |                  |
        ///             A                  C
        ///            / \\               //\
        ///           B    C     =>      A   D
        ///               / \           / \
        ///              E   D         B   E
        ///
        /// ```
        unsafe fn rotate_left(&mut self, node_a: NonNull<Node<T>>) -> Link<T> {
            unsafe {
                if let Some(parent) = (*node_a.as_ptr()).parent {
                    let mut node_a_from_left = false;
                    if let Some(p_node_a) = (*parent.as_ptr()).left
                        && std::ptr::eq(p_node_a.as_ptr(), node_a.as_ptr())
                    {
                        node_a_from_left = true;
                    }
                    let node_a = if node_a_from_left {
                        (*parent.as_ptr()).left.unwrap()
                    } else {
                        (*parent.as_ptr()).right.unwrap()
                    };
                    let node_c = (*node_a.as_ptr()).right.unwrap();
                    (*node_c.as_ptr()).is_red = (*node_a.as_ptr()).is_red;
                    (*node_a.as_ptr()).is_red = true;
                    (*node_c.as_ptr()).parent = Some(parent);
                    if node_c.as_ref().left.is_some() {
                        let mut node_e = (*node_c.as_ptr()).left;
                        if let Some(e) = &mut node_e {
                            (*e.as_ptr()).parent = Some(node_a);
                        }
                        (*node_a.as_ptr()).right = node_e;
                    } else {
                        (*node_a.as_ptr()).right = None;
                    }
                    (*node_c.as_ptr()).left = Some(node_a);
                    (*node_a.as_ptr()).parent = Some(node_c);
                    if node_a_from_left {
                        (*parent.as_ptr()).left = Some(node_c);
                        (*parent.as_ptr()).left
                    } else {
                        (*parent.as_ptr()).right = Some(node_c);
                        (*parent.as_ptr()).right
                    }
                } else {
                    let fixed_head = self.fixed_head.unwrap();
                    let node_a = (*fixed_head.as_ptr()).left.unwrap();
                    let node_c = (*node_a.as_ptr()).right.unwrap();
                    (*node_c.as_ptr()).is_red = (*node_a.as_ptr()).is_red;
                    (*node_a.as_ptr()).is_red = true;
                    if node_c.as_ref().left.is_some() {
                        let mut node_e = (*node_c.as_ptr()).left;
                        if let Some(e) = &mut node_e {
                            (*e.as_ptr()).parent = Some(node_a);
                        }
                        (*node_a.as_ptr()).right = node_e;
                    } else {
                        (*node_a.as_ptr()).right = None;
                    }
                    (*node_c.as_ptr()).left = Some(node_a);
                    (*node_a.as_ptr()).parent = Some(node_c);
                    (*node_c.as_ptr()).parent = None;
                    (*fixed_head.as_ptr()).left = Some(node_c);
                    (*fixed_head.as_ptr()).left
                }
            }
        }

        /// Rotate right without parent
        /// A is root
        ///
        /// ```text
        ///              A               B
        ///            // \             / \\
        ///            B   C     =>    E    A
        ///          // \                  / \
        ///         E    D                D   C
        /// ```
        ///
        /// Rotate right with parent
        ///
        /// ```text
        ///                P               P
        ///                |               |
        ///                A               B
        ///              // \             / \\
        ///              B   C     =>    E    A
        ///            // \                  / \
        ///           E    D                D   C
        ///
        /// ```
        unsafe fn rotate_right(&mut self, node_a: NonNull<Node<T>>) -> Link<T> {
            unsafe {
                if let Some(parent) = (*node_a.as_ptr()).parent {
                    let mut node_a_from_left = false;
                    if let Some(p_node_a) = (*parent.as_ptr()).left
                        && std::ptr::eq(p_node_a.as_ptr(), node_a.as_ptr())
                    {
                        node_a_from_left = true;
                    }
                    let node_a = if node_a_from_left {
                        (*parent.as_ptr()).left.unwrap()
                    } else {
                        (*parent.as_ptr()).right.unwrap()
                    };
                    let node_b = (*node_a.as_ptr()).left.unwrap();
                    (*node_b.as_ptr()).parent = Some(parent);
                    (*node_b.as_ptr()).is_red = (*node_a.as_ptr()).is_red;
                    (*node_a.as_ptr()).is_red = true;
                    if node_b.as_ref().right.is_some() {
                        let mut node_d = (*node_b.as_ptr()).right;
                        if let Some(d) = &mut node_d {
                            (*d.as_ptr()).parent = Some(node_a);
                        }
                        (*node_a.as_ptr()).left = node_d;
                    } else {
                        (*node_a.as_ptr()).left = None;
                    }
                    (*node_b.as_ptr()).right = Some(node_a);
                    (*node_a.as_ptr()).parent = Some(node_b);
                    if node_a_from_left {
                        (*parent.as_ptr()).left = Some(node_b);
                        (*parent.as_ptr()).left
                    } else {
                        (*parent.as_ptr()).right = Some(node_b);
                        (*parent.as_ptr()).right
                    }
                } else {
                    let fixed_head = self.fixed_head.unwrap();
                    let node_a = (*fixed_head.as_ptr()).left.unwrap();
                    let node_b = (*node_a.as_ptr()).left.unwrap();
                    (*node_b.as_ptr()).is_red = (*node_a.as_ptr()).is_red;
                    (*node_a.as_ptr()).is_red = true;
                    if node_b.as_ref().right.is_some() {
                        let mut node_d = (*node_b.as_ptr()).right;
                        if let Some(d) = &mut node_d {
                            (*d.as_ptr()).parent = Some(node_a);
                        }
                        (*node_a.as_ptr()).left = node_d;
                    } else {
                        (*node_a.as_ptr()).left = None;
                    }
                    (*node_b.as_ptr()).right = Some(node_a);
                    (*node_a.as_ptr()).parent = Some(node_b);
                    (*node_b.as_ptr()).parent = None;
                    (*fixed_head.as_ptr()).left = Some(node_b);
                    (*fixed_head.as_ptr()).left
                }
            }
        }

        /// Flip color
        ///
        /// ```text
        ///             |          ||
        ///             A    =>    A
        ///           // \\       / \
        ///          B    C      B   C
        ///
        /// ```
        unsafe fn flip_colors(&mut self, mut node: NonNull<Node<T>>) {
            unsafe {
                if node.as_ref().left.is_some() && node.as_ref().right.is_some() {
                    if let Some(ref mut left) = node.as_mut().left {
                        left.as_mut().is_red = false;
                    }
                    if let Some(ref mut right) = node.as_mut().right {
                        right.as_mut().is_red = false;
                    }
                    node.as_mut().is_red = true;

                    if (*node.as_ptr()).parent.is_none() {
                        node.as_mut().is_red = false;
                    }
                }
            }
        }

        unsafe fn check_put_balancing(&mut self, node: NonNull<Node<T>>) -> OperationPut {
            unsafe {
                if node.as_ref().right.is_some() {
                    let r = node.as_ref().right.unwrap();
                    if node.as_ref().left.is_some() && !node.as_ref().is_red {
                        let l = node.as_ref().left.unwrap();
                        if l.as_ref().is_red && r.as_ref().is_red {
                            return OperationPut::FlipColors;
                        }
                    }
                    if r.as_ref().is_red {
                        return OperationPut::Left;
                    }
                }
                if node.as_ref().is_red && node.as_ref().left.is_some() {
                    let l = node.as_ref().left.unwrap();
                    if l.as_ref().is_red {
                        return OperationPut::Right;
                    }
                }
                OperationPut::Nothing
            }
        }

        unsafe fn put_balancing(&mut self, next: NonNull<Node<T>>) {
            unsafe {
                let mut next = next;
                loop {
                    match self.check_put_balancing(next) {
                        OperationPut::Left => {
                            if (*next.as_ptr()).is_red {
                                if let Some(n) = self.rotate_left_right_flip_color(next) {
                                    next = n;
                                }
                            } else {
                                if let Some(n) = self.rotate_left(next) {
                                    next = n;
                                }
                            }
                        }
                        OperationPut::Right => {
                            if (*next.as_ptr()).parent.is_some() {
                                let node_a = (*next.as_ptr()).parent.unwrap();
                                if let Some(n) = self.rotate_right(node_a) {
                                    next = n;
                                }
                            }
                        }
                        OperationPut::FlipColors => {
                            self.flip_colors(next);
                            if (*next.as_ptr()).parent.is_some() {
                                next = (*next.as_ptr()).parent.unwrap();
                            } else {
                                break;
                            }
                        }
                        OperationPut::Nothing => {
                            break;
                        }
                    }
                }
            }
        }

        unsafe fn find_put_parent_candidate(&mut self, parent: Link<T>, elem: &T) -> Link<T> {
            unsafe {
                if let Some(parent) = parent {
                    match elem.cmp(&parent.as_ref().value) {
                        Ordering::Equal => None,
                        Ordering::Less => {
                            if (*parent.as_ptr()).left.is_some() {
                                self.find_put_parent_candidate((*parent.as_ptr()).left, elem)
                            } else {
                                Some(parent)
                            }
                        }
                        Ordering::Greater => {
                            if (*parent.as_ptr()).right.is_some() {
                                self.find_put_parent_candidate((*parent.as_ptr()).right, elem)
                            } else {
                                Some(parent)
                            }
                        }
                    }
                } else {
                    parent
                }
            }
        }

        unsafe fn attach_node(&mut self, parent: NonNull<Node<T>>, elem: T) -> bool {
            unsafe {
                match elem.cmp(&parent.as_ref().value) {
                    Ordering::Equal => false,
                    Ordering::Less => {
                        (*parent.as_ptr()).left = Node::new_red(elem, parent);
                        true
                    }
                    Ordering::Greater => {
                        (*parent.as_ptr()).right = Node::new_red(elem, parent);
                        true
                    }
                }
            }
        }

        /// Returns the default iterator over the tree.
        ///
        /// The default traversal is in-order (`LNR`), so values are yielded in
        /// ascending order.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([3, 1, 2]);
        ///
        /// let values: Vec<i32> = tree.iter().copied().collect();
        ///
        /// assert_eq!(values, vec![1, 2, 3]);
        /// ```
        pub fn iter(&self) -> IterInOrder<'_, T> {
            self.iter_inorder()
        }

        /// Returns an in-order (`LNR`) iterator.
        ///
        /// Values are yielded in ascending order.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([3, 1, 2]);
        ///
        /// assert_eq!(
        ///     tree.iter_inorder().copied().collect::<Vec<_>>(),
        ///     vec![1, 2, 3]
        /// );
        /// ```
        pub fn iter_inorder(&self) -> IterInOrder<'_, T> {
            unsafe { IterInOrder::new(leftmost_child_in_order(self.get_root()), self.count) }
        }

        /// Returns a reverse in-order (`RNL`) iterator.
        ///
        /// Values are yielded in descending order.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([3, 1, 2]);
        ///
        /// assert_eq!(
        ///     tree.iter_reverse_inorder().copied().collect::<Vec<_>>(),
        ///     vec![3, 2, 1]
        /// );
        /// ```
        pub fn iter_reverse_inorder(&self) -> IterReverseInOrder<'_, T> {
            unsafe {
                IterReverseInOrder::new(
                    rightmost_child_reverse_in_order(self.get_root()),
                    self.count,
                )
            }
        }

        /// Returns a pre-order (`NLR`) iterator.
        ///
        /// The current node is visited before its left and right subtrees.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([4, 2, 6, 1, 3, 5, 7]);
        ///
        /// let values: Vec<i32> = tree.iter_preorder().copied().collect();
        ///
        /// assert_eq!(values.len(), tree.len());
        /// ```
        pub fn iter_preorder(&self) -> IterPreOrder<'_, T> {
            IterPreOrder::new(self.get_root(), self.count)
        }

        /// Returns a post-order (`LRN`) iterator.
        ///
        /// The left and right subtrees are visited before the current node.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([4, 2, 6, 1, 3, 5, 7]);
        ///
        /// let values: Vec<i32> = tree.iter_postorder().copied().collect();
        ///
        /// assert_eq!(values.len(), tree.len());
        /// ```
        pub fn iter_postorder(&self) -> IterPostOrder<'_, T> {
            unsafe {
                let first = self.get_root().map(|root| leaf_post_order(root));
                IterPostOrder::new(first, self.count)
            }
        }

        /// Returns all values in level-order traversal.
        ///
        /// Nodes are visited level by level, starting from the root.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([4, 2, 6, 1, 3, 5, 7]);
        ///
        /// let values = tree.iter_level_order();
        ///
        /// assert_eq!(values.len(), tree.len());
        /// ```
        pub fn iter_level_order(&self) -> Vec<&T> {
            let mut ret: Vec<&T> = vec![];
            if let Some(root) = self.get_root() {
                iter_level_order_impl(root, &mut ret);
            }
            ret
        }
    }

    impl<'a, T: Ord + Default> std::iter::IntoIterator for &'a RedBlackTree<T> {
        type IntoIter = IterInOrder<'a, T>;
        type Item = &'a T;

        fn into_iter(self) -> Self::IntoIter {
            self.iter()
        }
    }

    impl<T: Ord + Default> Drop for RedBlackTree<T> {
        fn drop(&mut self) {
            unsafe {
                if let Some(fixed_head) = self.fixed_head {
                    self.remove_tree((*fixed_head.as_ptr()).left);
                    let _ = Box::from_raw(fixed_head.as_ptr());
                }
                self.fixed_head = None;
            }
        }
    }

    fn find_node<T: Ord>(fromnode: Link<T>, value: &T) -> Link<T> {
        unsafe {
            if let Some(fromnode) = fromnode {
                match value.cmp(&(*fromnode.as_ptr()).value) {
                    Ordering::Equal => Some(fromnode),
                    Ordering::Less => find_node((*fromnode.as_ptr()).left, value),
                    Ordering::Greater => find_node((*fromnode.as_ptr()).right, value),
                }
            } else {
                fromnode
            }
        }
    }

    fn helper_display_tree<T: Display>(node: NonNull<Node<T>>) -> String {
        unsafe {
            let mut s: String = "".into();
            let color = if (*node.as_ptr()).is_red {
                "[color=\"red\"]"
            } else {
                "[color=\"black\"]"
            };

            if let Some(left) = (*node.as_ptr()).left {
                s.push_str(&format!(
                    "\t{n1}->{n2} {color1}; {n1} {color1}; {n2} {color2};\n",
                    n1 = (*node.as_ptr()).value,
                    n2 = (*left.as_ptr()).value,
                    color1 = color,
                    color2 = if (*left.as_ptr()).is_red {
                        "[color=\"red\"]"
                    } else {
                        "[color=\"black\"]"
                    },
                ));
                s.push_str(&helper_display_tree(left));
            } else if (*node.as_ptr()).right.is_some() {
                s.push_str(&format!(
                    "\t{n1}->node_null_{n1} [color=\"grey\"]; {n1} {color1};\n",
                    n1 = (*node.as_ptr()).value,
                    color1 = color
                ));
                s.push_str(&format!(
                    "\tnode_null_{n1}[label=\"null\"]\n",
                    n1 = (*node.as_ptr()).value
                ));
            }

            if let Some(right) = (*node.as_ptr()).right {
                s.push_str(&format!(
                    "\t{n1}->{n2} {color1}; {n1} {color1}; {n2} {color2};\n",
                    n1 = (*node.as_ptr()).value,
                    n2 = (*right.as_ptr()).value,
                    color2 = if (*right.as_ptr()).is_red {
                        "[color=\"red\"]"
                    } else {
                        "[color=\"black\"]"
                    },
                    color1 = color
                ));
                s.push_str(&helper_display_tree(right));
            } else {
                s.push_str(&format!(
                    "\t{n1}->node_null_{n1} [color=\"grey\"]; {n1} {color1};\n",
                    n1 = (*node.as_ptr()).value,
                    color1 = color
                ));
                s.push_str(&format!(
                    "\tnode_null_{}[label=\"null\"]\n",
                    (*node.as_ptr()).value
                ));
            }
            s
        }
    }

    impl<T: Ord + Default> Default for RedBlackTree<T> {
        fn default() -> Self {
            Self::new()
        }
    }

    impl<T: Ord + Default + Clone> Clone for RedBlackTree<T> {
        fn clone(&self) -> Self {
            let mut new_list = Self::new();
            for value in self {
                new_list.insert(value.clone());
            }
            new_list
        }
    }

    impl<T: Ord + Default> Extend<T> for RedBlackTree<T> {
        fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
            for value in iter {
                self.insert(value);
            }
        }
    }

    impl<T: Ord + Default> FromIterator<T> for RedBlackTree<T> {
        fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
            let mut list = Self::new();
            list.extend(iter);
            list
        }
    }

    impl<T: Ord + Default + Debug> Debug for RedBlackTree<T> {
        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
            f.debug_list().entries(self).finish()
        }
    }

    impl<T: Ord + Default> PartialEq for RedBlackTree<T> {
        fn eq(&self, other: &Self) -> bool {
            self.len() == other.len() && self.iter_inorder().eq(other.iter_inorder())
        }
    }

    impl<T: Ord + Default> Eq for RedBlackTree<T> {}

    impl<T: Ord + Default> PartialOrd for RedBlackTree<T> {
        fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
            Some(self.cmp(other))
        }
    }

    impl<T: Ord + Default> Ord for RedBlackTree<T> {
        fn cmp(&self, other: &Self) -> Ordering {
            self.iter_inorder().cmp(other.iter_inorder())
        }
    }

    impl<T: Ord + Default + std::hash::Hash> std::hash::Hash for RedBlackTree<T> {
        fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
            self.len().hash(state);
            for item in self {
                item.hash(state);
            }
        }
    }
}

7. Поиск соседних значений

predecessor(x) и successor(x) нужны, когда важно быстро найти предыдущее и следующее значение относительно заданного элемента.

Подходит для:

  • предыдущее / следующее событие
  • соседний timestamp
  • ближайшая меньшая / большая цена
  • предыдущий / следующий ID
  • соседняя точка на шкале

Возьмём расписание событий:

09:00
10:30
12:00
14:15
16:00

Нужно для события 12:00 узнать, что было прямо перед ним и что идёт сразу после.


fn main() {
    let mut schedule = RedBlackTree::new();

    for time in [900, 1030, 1200, 1415, 1600] {
        schedule.insert(time);
    }

    let current = 1200;

    println!(
        "Предыдущее событие перед {}: {:?}",
        current,
        schedule.predecessor(&current)
    );

    println!(
        "Следующее событие после {}: {:?}",
        current,
        schedule.successor(&current)
    );
}














/// -------------------------------------------
/// Implementation RBT
/// -------------------------------------------


pub use tree::RedBlackTree;
pub use iter::{IterInOrder, Range};
pub use iter::IterPreOrder;
pub use iter::IterReverseInOrder;
pub use iter::IterPostOrder;
 
pub mod iter{
    use std::ptr::NonNull;

    use crate::node::{Link, Node};

    ///```text
    ///
    ///            4
    ///          /   \
    ///         2     9
    ///        / \   //\
    ///       1   3  7   10
    ///             / \
    ///            6   8
    ///```
    ///    Depth-First Search / Pre-order (NLR):     4, 2, 1, 3, 9, 7, 6, 8, 10
    ///    Depth-First Search / In-order (LNR):      1, 2, 3, 4, 6, 7, 8, 9, 10
    ///    Depth-First Search / Post-order (LRN):    1, 3, 2, 6, 8, 7, 10, 9, 4
    ///    Breadth-First Search / Level-order:       4, 2, 9, 1, 3, 7, 10, 6, 8 
    pub use dfs_in_order::{IterInOrder, Range};

    pub(crate) use dfs_in_order::{leftmost_child_in_order, successor_of_node_in_order};

    mod dfs_in_order {
        use super::{Link, Node, NonNull};
        use std::iter::FusedIterator;
        use std::marker::PhantomData;

        /// Returns the next node in an in-order (`LNR`) traversal.
        ///
        /// # Safety
        ///
        /// `node` must point to a live node that belongs to the current tree, and
        /// all parent/child links reachable from it must be valid.
        pub unsafe fn successor_of_node_in_order<T>(node: NonNull<Node<T>>) -> Link<T> {
            unsafe {
                if node.as_ref().right.is_some() {
                    // If a right subtree exists, the successor is its leftmost node.
                    leftmost_child_in_order(node.as_ref().right)
                } else {
                    // Otherwise, walk up through parent links until the current
                    // node is found in a left subtree.
                    parent_with_left(node)
                }
            }
        }

        /// Returns the leftmost node reachable from `node`.
        ///
        /// Returns `None` when `node` is `None`.
        ///
        /// # Safety
        ///
        /// Every pointer reachable through `left` links must refer to a live node.
        pub unsafe fn leftmost_child_in_order<T>(node: Link<T>) -> Link<T> {
            unsafe {
                if let Some(node) = node {
                    if node.as_ref().left.is_none() {
                        Some(node)
                    } else {
                        leftmost_child_in_order(node.as_ref().left)
                    }
                } else {
                    node
                }
            }
        }

        /// Walks up the parent chain until an ancestor is reached from its left child.
        ///
        /// # Safety
        ///
        /// `node` and all parent links traversed by this function must be valid.
        unsafe fn parent_with_left<T>(node: NonNull<Node<T>>) -> Link<T> {
            unsafe {
                let parent = node.as_ref().parent;
                if let Some(parent) = parent
                    && let Some(left) = parent.as_ref().left
                {
                    if std::ptr::eq(left.as_ptr(), node.as_ptr()) {
                        return Some(parent);
                    }
                    return parent_with_left(parent);
                }
                // No parent means that the root has been reached.
                None
            }
        }

        /// Iterator over a tree in in-order (`Left -> Node -> Right`, or `LNR`).
        ///
        /// For a binary search tree, this traversal yields values in ascending order.
        pub struct IterInOrder<'a, T> {
            current_node: Link<T>,
            count: usize,
            elem: Option<&'a T>,
            _boo: PhantomData<&'a T>,
        }

        impl<'a, T> IterInOrder<'a, T> {
            /// Creates an in-order iterator starting at `node`.
            pub(crate) fn new(node: Link<T>, count: usize) -> Self {
                Self {
                    current_node: node,
                    count,
                    elem: None,
                    _boo: PhantomData,
                }
            }
        }

        impl<'a, T> Iterator for IterInOrder<'a, T> {
            type Item = &'a T;

            fn next(&mut self) -> Option<Self::Item> {
                if self.count > 0 {
                    self.count -= 1;
                    if let Some(node) = self.current_node {
                        unsafe {
                            self.elem = Some(&node.as_ref().value);
                            self.current_node = successor_of_node_in_order(node);
                        }
                    } else {
                        self.elem = None;
                    }
                } else {
                    self.elem = None;
                }
                self.elem
            }

            fn size_hint(&self) -> (usize, Option<usize>) {
                (self.count, Some(self.count))
            }
        }

        impl<'a, T> ExactSizeIterator for IterInOrder<'a, T> {
            fn len(&self) -> usize {
                self.count
            }
        }

        impl<'a, T> FusedIterator for IterInOrder<'a, T> {}

        /// A lazy iterator over an inclusive range of values in a [`crate::RedBlackTree`].
        ///
        /// `Range` is created by [`crate::RedBlackTree::range`]. It yields references to
        /// values in ascending order, starting from the first value greater than or
        /// equal to the lower bound and stopping after the upper bound.
        ///
        /// The iterator does not allocate an intermediate collection. Values are
        /// produced one at a time as the iterator advances.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([1, 3, 5, 7, 9, 11]);
        ///
        /// let values: Vec<_> = tree
        ///     .range(&3, &9)
        ///     .copied()
        ///     .collect();
        ///
        /// assert_eq!(values, vec![3, 5, 7, 9]);
        /// ```
        ///
        /// The iterator can be combined with standard iterator adapters:
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend(1..=100);
        ///
        /// let values: Vec<_> = tree
        ///     .range(&20, &80)
        ///     .take(3)
        ///     .copied()
        ///     .collect();
        ///
        /// assert_eq!(values, vec![20, 21, 22]);
        /// ```
        pub struct Range<'a, T> {
            current_node: Link<T>,
            end_node: Link<T>,
            _marker: PhantomData<&'a T>,
        }

        impl<'a, T: Ord> Range<'a, T> {
            pub(crate) fn new(root: Link<T>, min: &T, max: &T) -> Self {
                if min > max {
                    return Self {
                        current_node: None,
                        end_node: None,
                        _marker: PhantomData,
                    };
                }

                unsafe {
                    let mut current = root;
                    let mut start: Link<T> = None;

                    // First node >= min.
                    while let Some(node) = current {
                        match node.as_ref().value.cmp(min) {
                            std::cmp::Ordering::Less => {
                                current = node.as_ref().right;
                            }

                            std::cmp::Ordering::Equal => {
                                start = Some(node);
                                break;
                            }

                            std::cmp::Ordering::Greater => {
                                start = Some(node);
                                current = node.as_ref().left;
                            }
                        }
                    }

                    current = root;

                    let mut end: Link<T> = None;

                    // First node > max.
                    while let Some(node) = current {
                        match node.as_ref().value.cmp(max) {
                            std::cmp::Ordering::Less | std::cmp::Ordering::Equal => {
                                current = node.as_ref().right;
                            }

                            std::cmp::Ordering::Greater => {
                                end = Some(node);
                                current = node.as_ref().left;
                            }
                        }
                    }

                    Self {
                        current_node: start,
                        end_node: end,
                        _marker: PhantomData,
                    }
                }
            }
        }

        impl<'a, T> Iterator for Range<'a, T> {
            type Item = &'a T;

            fn next(&mut self) -> Option<Self::Item> {
                let node = self.current_node?;

                if self.end_node == Some(node) {
                    self.current_node = None;
                    return None;
                }

                unsafe {
                    let value = &node.as_ref().value;

                    self.current_node = successor_of_node_in_order(node);

                    Some(value)
                }
            }
        }
    }

    pub use dfs_reverse_in_order::IterReverseInOrder;

    pub(crate) use dfs_reverse_in_order::{
        rightmost_child_reverse_in_order, successor_of_node_reverse_in_order,
    };

    mod dfs_reverse_in_order {
        use super::{Link, Node, NonNull};
        use std::marker::PhantomData;

        /// Returns the next node in reverse in-order (`Right -> Node -> Left`, or `RNL`).
        ///
        /// # Safety
        ///
        /// `node` must point to a live node that belongs to the current tree, and
        /// all parent/child links reachable from it must be valid.
        pub unsafe fn successor_of_node_reverse_in_order<T>(node: NonNull<Node<T>>) -> Link<T> {
            unsafe {
                if node.as_ref().left.is_some() {
                    // After the current node, descend into the left subtree and
                    // choose its rightmost node.
                    rightmost_child_reverse_in_order(node.as_ref().left)
                } else {
                    // Without a left subtree, walk upward until reaching an
                    // ancestor from its right subtree.
                    parent_with_right(node)
                }
            }
        }

        /// Returns the rightmost node reachable from `node`.
        ///
        /// Returns `None` when `node` is `None`.
        ///
        /// # Safety
        ///
        /// Every pointer reachable through `right` links must refer to a live node.
        pub unsafe fn rightmost_child_reverse_in_order<T>(node: Link<T>) -> Link<T> {
            unsafe {
                if let Some(node) = node {
                    if node.as_ref().right.is_none() {
                        Some(node)
                    } else {
                        rightmost_child_reverse_in_order(node.as_ref().right)
                    }
                } else {
                    None
                }
            }
        }

        /// Walks up the parent chain until an ancestor is reached from its right child.
        ///
        /// # Safety
        ///
        /// `node` and all parent links traversed by this function must be valid.
        unsafe fn parent_with_right<T>(node: NonNull<Node<T>>) -> Link<T> {
            unsafe {
                let parent = node.as_ref().parent;

                if let Some(parent) = parent
                    && let Some(right) = parent.as_ref().right
                {
                    if std::ptr::eq(right.as_ptr(), node.as_ptr()) {
                        return Some(parent);
                    }

                    return parent_with_right(parent);
                }

                None
            }
        }

        /// Iterator over a tree in reverse in-order (`Right -> Node -> Left`, or `RNL`).
        ///
        /// For a binary search tree, this traversal yields values in descending order.
        pub struct IterReverseInOrder<'a, T> {
            current_node: Link<T>,
            count: usize,
            elem: Option<&'a T>,
            _boo: PhantomData<&'a T>,
        }

        impl<'a, T> IterReverseInOrder<'a, T> {
            /// Creates a reverse in-order iterator starting at `node`.
            pub(crate) fn new(node: Link<T>, count: usize) -> Self {
                Self {
                    current_node: node,
                    count,
                    elem: None,
                    _boo: PhantomData,
                }
            }
        }

        impl<'a, T> Iterator for IterReverseInOrder<'a, T> {
            type Item = &'a T;

            fn next(&mut self) -> Option<Self::Item> {
                if self.count > 0 {
                    self.count -= 1;

                    if let Some(node) = self.current_node {
                        unsafe {
                            self.elem = Some(&node.as_ref().value);
                            self.current_node = successor_of_node_reverse_in_order(node);
                        }
                    } else {
                        self.elem = None;
                    }
                } else {
                    self.elem = None;
                }

                self.elem
            }

            fn size_hint(&self) -> (usize, Option<usize>) {
                (self.count, Some(self.count))
            }
        }
    }

    pub use dfs_pre_order::IterPreOrder;

    pub(crate) use dfs_pre_order::successor_of_node_pre_order;

    mod dfs_pre_order {
        use super::{Link, Node, NonNull};
        use std::marker::PhantomData;

        /// Returns the next node in a pre-order (`Node -> Left -> Right`, or `NLR`) traversal.
        ///
        /// # Safety
        ///
        /// `node` must point to a live node in the current tree and all traversed
        /// links must be valid.
        pub unsafe fn successor_of_node_pre_order<T>(node: NonNull<Node<T>>) -> Link<T> {
            unsafe {
                if let Some(node) = node.as_ref().left {
                    Some(node)
                } else if let Some(node) = node.as_ref().right {
                    Some(node)
                } else {
                    right_with_parent(node)
                }
            }
        }

        /// Finds the next right subtree by walking through parent links.
        ///
        /// # Safety
        ///
        /// `node` and all parent links traversed by this function must be valid.
        unsafe fn right_with_parent<T>(node: NonNull<Node<T>>) -> Link<T> {
            unsafe {
                if let Some(parent) = node.as_ref().parent {
                    next_right(Some(parent), node)
                } else {
                    None
                }
            }
        }

        /// Searches ancestors for the next unvisited right child.
        ///
        /// # Safety
        ///
        /// `child`, `node`, and all links traversed by this function must be valid.
        unsafe fn next_right<T>(node: Link<T>, child: NonNull<Node<T>>) -> Link<T> {
            unsafe {
                if let Some(n) = node {
                    if let Some(right) = n.as_ref().right {
                        if std::ptr::eq(right.as_ptr(), child.as_ptr()) {
                            next_right(n.as_ref().parent, n)
                        } else {
                            Some(right)
                        }
                    } else {
                        next_right(n.as_ref().parent, n)
                    }
                } else {
                    None
                }
            }
        }

        /// Iterator over a tree in pre-order (`Node -> Left -> Right`, or `NLR`).
        ///
        /// Pre-order traversal visits a node before either of its subtrees.
        pub struct IterPreOrder<'a, T> {
            current_node: Link<T>,
            count: usize,
            elem: Option<&'a T>,
            _boo: PhantomData<&'a T>,
        }

        impl<'a, T> IterPreOrder<'a, T> {
            /// Creates a pre-order iterator starting at `root`.
            pub(crate) fn new(root: Link<T>, count: usize) -> Self {
                Self {
                    current_node: root,
                    count,
                    elem: None,
                    _boo: PhantomData,
                }
            }
        }

        impl<'a, T> Iterator for IterPreOrder<'a, T> {
            type Item = &'a T;

            fn next(&mut self) -> Option<Self::Item> {
                if self.count > 0 {
                    self.count -= 1;
                    if let Some(node) = self.current_node {
                        unsafe {
                            self.elem = Some(&node.as_ref().value);
                            self.current_node = successor_of_node_pre_order(node);
                        }
                    } else {
                        self.elem = None;
                    }
                } else {
                    self.elem = None;
                }
                self.elem
            }

            fn size_hint(&self) -> (usize, Option<usize>) {
                (self.count, Some(self.count))
            }
        }
    }

    pub use dfs_post_order::IterPostOrder;

    pub(crate) use dfs_post_order::{leaf_post_order, successor_of_node_post_order};

    mod dfs_post_order {
        use super::{Link, Node, NonNull};
        use std::marker::PhantomData;

        /// Returns the next node in a post-order (`Left -> Right -> Node`, or `LRN`) traversal.
        ///
        /// # Safety
        ///
        /// `current_node` must point to a live node in the current tree and all
        /// traversed parent/child links must be valid.
        pub unsafe fn successor_of_node_post_order<T>(current_node: NonNull<Node<T>>) -> Link<T> {
            unsafe {
                if let Some(parent) = current_node.as_ref().parent {
                    if let Some(right) = parent.as_ref().right {
                        if std::ptr::eq(current_node.as_ptr(), right.as_ptr()) {
                            Some(parent)
                        } else {
                            Some(leaf_post_order(right))
                        }
                    } else {
                        Some(parent)
                    }
                } else {
                    None
                }
            }
        }

        /// Returns the first leaf visited by a post-order traversal starting at `node`.
        ///
        /// # Safety
        ///
        /// `node` must point to a live node and all descendant links traversed by
        /// this function must be valid.
        pub unsafe fn leaf_post_order<T>(node: NonNull<Node<T>>) -> NonNull<Node<T>> {
            unsafe {
                if let Some(left) = node.as_ref().left {
                    leaf_post_order(left)
                } else if let Some(right) = node.as_ref().right {
                    leaf_post_order(right)
                } else {
                    node
                }
            }
        }

        /// Iterator over a tree in post-order (`Left -> Right -> Node`, or `LRN`).
        ///
        /// Post-order traversal visits both subtrees before the current node.
        pub struct IterPostOrder<'a, T> {
            current_node: Link<T>,
            count: usize,
            _boo: PhantomData<&'a T>,
        }

        impl<'a, T> IterPostOrder<'a, T> {
            /// Creates a post-order iterator starting at the first post-order node.
            pub(crate) fn new(root: Link<T>, count: usize) -> Self {
                Self {
                    current_node: root,
                    count,
                    _boo: PhantomData,
                }
            }
        }

        impl<'a, T> Iterator for IterPostOrder<'a, T> {
            type Item = &'a T;

            fn next(&mut self) -> Option<Self::Item> {
                if self.count == 0 {
                    return None;
                }

                let node = self.current_node?;

                unsafe {
                    let value = &node.as_ref().value;
                    self.current_node = successor_of_node_post_order(node);
                    self.count -= 1;
                    Some(value)
                }
            }

            fn size_hint(&self) -> (usize, Option<usize>) {
                (self.count, Some(self.count))
            }
        }
    }

    /// Breadth-First Search
    mod bfs {
        use super::{Node, NonNull};
        use std::collections::VecDeque;

        /// Appends tree values to `ret` in breadth-first / level-order.
        pub fn iter_level_order_impl<T>(root: NonNull<Node<T>>, ret: &mut Vec<&T>) {
            let mut deque: VecDeque<NonNull<Node<T>>> = VecDeque::new();
            unsafe {
                deque.push_back(root);
                let mut node: NonNull<Node<T>>;
                while !deque.is_empty() {
                    node = deque.pop_front().unwrap();
                    ret.push(&node.as_ref().value);
                    if let Some(left) = node.as_ref().left {
                        deque.push_back(left);
                    }
                    if let Some(right) = node.as_ref().right {
                        deque.push_back(right);
                    }
                }
            }
        }
    }

    pub(crate) use bfs::iter_level_order_impl;
}

/// Internal node representation used by the Red-Black Tree.
///
/// Nodes are allocated on the heap and connected using [`NonNull`] pointers.
/// The tree owns the allocated nodes and is responsible for releasing them.
///
/// `Node` and [`Link`] are crate-private implementation details and are not
/// exposed through the public API.
pub mod node{

    use std::ptr::NonNull;

    /// A single node in the Red-Black Tree.
    ///
    /// Each node stores:
    ///
    /// - a link to its left child;
    /// - a link to its right child;
    /// - a link to its parent;
    /// - its Red-Black color;
    /// - the stored value.
    ///
    /// Tree links are represented by [`Link<T>`], which is an
    /// `Option<NonNull<Node<T>>>`.
    ///
    /// A `None` link represents the absence of a parent or child, while
    /// `Some(pointer)` refers to another allocated node.
    ///
    /// Memory ownership is managed by [`crate::RedBlackTree`]. The pointers stored
    /// here are non-owning links between nodes.
    #[derive(Debug)]
    pub(crate) struct Node<T> {
        /// Left child of this node.
        pub(crate) left: Link<T>,

        /// Right child of this node.
        pub(crate) right: Link<T>,

        /// Parent of this node.
        ///
        /// The root node has no parent.
        pub(crate) parent: Link<T>,

        /// Red-Black color of the node.
        ///
        /// `true` means red and `false` means black.
        pub(crate) is_red: bool,

        /// Value stored in this node.
        pub(crate) value: T,
    }

    /// A link between nodes in the tree.
    ///
    /// `None` represents a missing parent or child.
    ///
    /// `Some(ptr)` contains a non-null pointer to another allocated [`Node`].
    ///
    /// Using `Option<NonNull<Node<T>>>` allows the implementation to represent
    /// nullable tree links while keeping direct pointer-based navigation between
    /// parents and children.
    pub(crate) type Link<T> = Option<NonNull<Node<T>>>;

    impl<T: Default> Node<T> {
        /// Creates the sentinel head node together with the initial tree root.
        ///
        /// The sentinel does not represent a value stored by the user. Its
        /// `value` field is initialized with [`Default::default`] and its left
        /// child becomes the first actual node in the tree.
        ///
        /// The initial root node is created as black, as required by the
        /// Red-Black Tree invariants.
        ///
        /// # Returns
        ///
        /// A link to the newly allocated sentinel node.
        ///
        /// # Implementation
        ///
        /// Both the sentinel and the root node are allocated on the heap.
        /// Ownership of these allocations is transferred to the tree and later
        /// recovered when the tree releases its nodes.
        pub(crate) fn new_fixed_head(value: T) -> Link<T> {
            let fixed_head = Box::into_non_null(Box::new(Self {
                left: None,
                right: None,
                parent: None,
                is_red: false,
                value: T::default(),
            }));
            unsafe {
                (*fixed_head.as_ptr()).left = Node::new_black(value);
            }
            Some(fixed_head)
        }
    }

    impl<T> Node<T> {
        /// Allocates a new black node.
        ///
        /// The node is created without a parent or children.
        ///
        /// # Returns
        ///
        /// A non-null link to the newly allocated node.
        ///
        /// The allocation becomes owned by the tree and must eventually be
        /// released by the tree implementation.
        pub(crate) fn new_black(value: T) -> Link<T> {
            let new = Box::into_non_null(Box::new(Self {
                left: None,
                right: None,
                parent: None,
                is_red: false,
                value,
            }));

            Some(new)
        }

        /// Allocates a new red node with the specified parent.
        ///
        /// Newly inserted Red-Black Tree nodes are initially red. The balancing
        /// algorithm may later recolor the node or rotate the surrounding
        /// subtree.
        ///
        /// The new node has no children.
        ///
        /// # Parameters
        ///
        /// - `value` — value stored in the node.
        /// - `parent` — non-null pointer to the node's parent.
        ///
        /// # Returns
        ///
        /// A non-null link to the newly allocated node.
        ///
        /// The allocation becomes owned by the tree and must eventually be
        /// released by the tree implementation.
        pub(crate) fn new_red(value: T, parent: NonNull<Node<T>>) -> Link<T> {
            let new = Box::into_non_null(Box::new(Self {
                left: None,
                right: None,
                parent: Some(parent),
                is_red: true,
                value,
            }));

            Some(new)
        }
    }
}


pub mod validation{
    use crate::node::Link;
    use crate::tree::RedBlackTree;

    impl<T: Ord + Default> RedBlackTree<T> {
        // red-red violations,
        // min black-height,
        // max black-height,
        // BST ordering,
        // parent links,
        // reachable node count
        unsafe fn validate(
            node: &Link<T>,
            expected_parent: Link<T>,
            parent_is_red: bool,
            black_height: usize,
            min: Option<&T>,
            max: Option<&T>,
        ) -> (usize, usize, usize, bool, bool, usize) {
            unsafe {
                if let Some(n) = node {
                    let value = &n.as_ref().value;

                    // 1. Check parent
                    let parent_valid = match (n.as_ref().parent, expected_parent) {
                        (None, None) => true,

                        (Some(actual), Some(expected)) => {
                            std::ptr::eq(actual.as_ptr(), expected.as_ptr())
                        }

                        _ => false,
                    };

                    // 2. Check BST ordering
                    if let Some(min) = min
                        && value <= min
                    {
                        return (0, 0, 0, false, parent_valid, 1);
                    }

                    if let Some(max) = max
                        && value >= max
                    {
                        return (0, 0, 0, false, parent_valid, 1);
                    }

                    let is_red = n.as_ref().is_red;

                    // 3. A red node cannot have a red parent.
                    let red_red = if parent_is_red && is_red { 1 } else { 0 };

                    // 4. Black height
                    let black_height = if is_red {
                        black_height
                    } else {
                        black_height + 1
                    };

                    let left = Self::validate(
                        &n.as_ref().left,
                        Some(*n),
                        is_red,
                        black_height,
                        min,
                        Some(value),
                    );

                    let right = Self::validate(
                        &n.as_ref().right,
                        Some(*n),
                        is_red,
                        black_height,
                        Some(value),
                        max,
                    );

                    (
                        red_red + left.0 + right.0,
                        std::cmp::min(left.1, right.1),
                        std::cmp::max(left.2, right.2),
                        left.3 && right.3,
                        parent_valid && left.4 && right.4,
                        1 + left.5 + right.5,
                    )
                } else {
                    (0, black_height, black_height, true, true, 0)
                }
            }
        }

        pub fn is_valid(&self) -> bool {
            unsafe {
                // tree is empty
                if self.count == 0 {
                    return match self.fixed_head {
                        None => true,

                        Some(fixed_head) => (*fixed_head.as_ptr()).left.is_none(),
                    };
                }

                // count > 0, so sentinel must exist.
                let Some(fixed_head) = self.fixed_head else {
                    return false;
                };

                // And root must exist.
                let root_link = (*fixed_head.as_ptr()).left;

                let Some(root) = root_link else {
                    return false;
                };

                // Root is always BLACK
                if root.as_ref().is_red {
                    return false;
                }

                // Root has no parent
                if root.as_ref().parent.is_some() {
                    return false;
                }

                let result = Self::validate(&root_link, None, false, 0, None, None);

                let red_red = result.0;
                let black_height_min = result.1;
                let black_height_max = result.2;
                let bst_valid = result.3;
                let parents_valid = result.4;
                let reachable_nodes = result.5;

                red_red == 0
                    && black_height_min == black_height_max
                    && bst_valid
                    && parents_valid
                    && reachable_nodes == self.count
            }
        }
    }
}


pub mod tree{
    use std::cmp::Ordering;
    use std::fmt::{Debug, Display};

    use crate::node::{Link, Node};

    use std::marker::PhantomData;
    use std::ptr::NonNull;

    use crate::iter::{IterInOrder, Range, leftmost_child_in_order, successor_of_node_in_order};

    use crate::iter::{
        IterReverseInOrder, rightmost_child_reverse_in_order, successor_of_node_reverse_in_order,
    };

    use crate::iter::{IterPreOrder, successor_of_node_pre_order};

    use crate::iter::{IterPostOrder, leaf_post_order, successor_of_node_post_order};

    use crate::iter::iter_level_order_impl;

    /// A self-balancing Red-Black Tree.
    ///
    /// `RedBlackTree` stores unique values in sorted order.
    ///
    /// Insert, lookup and removal operations have logarithmic
    /// expected tree height due to Red-Black Tree balancing.
    ///
    /// # Examples
    ///
    /// ```
    /// use rbtree_extended::RedBlackTree;
    ///
    /// let mut tree = RedBlackTree::new();
    ///
    /// tree.insert(3);
    /// tree.insert(1);
    /// tree.insert(2);
    ///
    /// assert_eq!(tree.len(), 3);
    /// assert!(tree.contains(&2));
    /// ```
    pub struct RedBlackTree<T: Ord + Default> {
        pub(crate) fixed_head: Link<T>,
        pub(crate) count: usize,
        _marker: PhantomData<T>,
    }

    enum OperationPut {
        Left,
        Right,
        FlipColors,
        Nothing,
    }

    enum OperationRemove {
        RedLeaf,
        BlackLeaf,
        NodeWithChildren,
        BlackNodeWithRedLeaf,
    }

    enum OperationRemoveBlackLeaf {
        LeftRedABlackBRedCleaf,                      // 2.1.1.1
        RightRedABlackBRedCleaf,                     // 2.1.1.2
        LeftRedABlackBleaf,                          // 2.1.2.1
        RightRedABlackBleaf,                         // 2.1.2.2
        BlackARedBWithBlackChildrenLeaf,             // 2.2.4
        BlackARedBWithBlackChildrenRightHaveRedLeaf, // 2.2.1
        BlackALeftBlackBRedDleaf,                    // 2.3.1.1
        BlackARightBlackBRedDleaf,                   // 2.3.1.2
        BlackALeftBlackBleaf,                        // 2.3.2.1
        BlackARightBlackBleaf,                       // 2.3.2.2
        Root,
        Unimplemented,
    }

    impl<T: Ord + Default + Display> RedBlackTree<T> {
        /// Exports the tree in Graphviz DOT format.
        ///
        /// The returned string can be rendered using Graphviz-compatible tools.
        ///
        /// An empty tree produces a valid empty DOT graph.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.insert(10);
        /// tree.insert(5);
        /// tree.insert(20);
        ///
        /// let dot = tree.to_dot();
        ///
        /// println!("{dot}");
        /// ```
        pub fn to_dot(&self) -> String {
            unsafe {
                let Some(fixed_head) = self.fixed_head else {
                    return "digraph Tree {}".into();
                };

                let Some(root) = (*fixed_head.as_ptr()).left else {
                    return "digraph Tree {}".into();
                };

                format!(
                    "\ndigraph Tree {{\n\tratio = fill;\n\tnode [style=filled fontcolor=\"white\"];\n{}}}",
                    helper_display_tree(root)
                )
            }
        }
    }

    impl<T: Ord + Default> RedBlackTree<T> {
        /// Creates an empty Red-Black Tree.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let tree = RedBlackTree::<i32>::new();
        ///
        /// assert!(tree.is_empty());
        /// ```
        pub fn new() -> Self {
            Self {
                fixed_head: None,
                count: 0,
                _marker: PhantomData,
            }
        }

        /// Returns the number of values stored in the tree.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.insert(10);
        /// tree.insert(20);
        ///
        /// assert_eq!(tree.len(), 2);
        /// ```
        pub fn len(&self) -> usize {
            self.count
        }

        /// Returns `true` if the tree contains no values.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::<i32>::new();
        /// assert!(tree.is_empty());
        ///
        /// tree.insert(10);
        /// assert!(!tree.is_empty());
        /// ```
        pub fn is_empty(&self) -> bool {
            self.count == 0
        }

        /// Removes all values from the tree.
        ///
        /// After calling `clear`, the tree is empty and can be reused.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([1, 2, 3]);
        ///
        /// tree.clear();
        ///
        /// assert!(tree.is_empty());
        /// assert_eq!(tree.len(), 0);
        /// ```
        pub fn clear(&mut self) {
            unsafe {
                if let Some(fixed_head) = self.fixed_head {
                    let root = (*fixed_head.as_ptr()).left;

                    (*fixed_head.as_ptr()).left = None;

                    self.remove_tree(root);
                }

                debug_assert_eq!(self.count, 0);
            }
        }

        /// Returns the smallest value in the tree.
        ///
        /// Returns `None` if the tree is empty.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([8, 3, 10, 1]);
        ///
        /// assert_eq!(tree.first(), Some(&1));
        /// ```
        pub fn first(&self) -> Option<&T> {
            self.minimum()
        }

        /// Returns the largest value in the tree.
        ///
        /// Returns `None` if the tree is empty.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([8, 3, 10, 14]);
        ///
        /// assert_eq!(tree.last(), Some(&14));
        /// ```
        pub fn last(&self) -> Option<&T> {
            self.maximum()
        }

        fn minimum(&self) -> Option<&T> {
            unsafe {
                let root = self.get_root()?;
                let node = self.find_min(root);
                Some(&node.as_ref().value)
            }
        }

        fn maximum(&self) -> Option<&T> {
            unsafe {
                let root = self.get_root()?;
                let node = self.find_max(root);

                Some(&node.as_ref().value)
            }
        }

        /// Returns the height of the tree.
        ///
        /// An empty tree has height `0`.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// assert_eq!(tree.height(), 0);
        ///
        /// tree.insert(10);
        /// assert_eq!(tree.height(), 1);
        /// ```
        pub fn height(&self) -> usize {
            unsafe fn height_from<T>(node: Link<T>) -> usize {
                unsafe {
                    match node {
                        None => 0,

                        Some(node) => {
                            let left_height = height_from(node.as_ref().left);
                            let right_height = height_from(node.as_ref().right);

                            1 + left_height.max(right_height)
                        }
                    }
                }
            }

            unsafe { height_from(self.get_root()) }
        }

        /// Returns `true` if the tree contains `value`.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([1, 3, 5]);
        ///
        /// assert!(tree.contains(&3));
        /// assert!(!tree.contains(&4));
        /// ```
        pub fn contains(&self, value: &T) -> bool {
            !find_node(self.get_root(), value).is_none()
        }

        /// Inserts a value into the tree.
        ///
        /// Returns `true` if the value was inserted.
        ///
        /// Returns `false` if the value already exists.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        ///
        /// assert!(tree.insert(10));
        /// assert!(!tree.insert(10));
        /// ```
        pub fn insert(&mut self, value: T) -> bool {
            unsafe {
                if let Some(fixed_head) = self.fixed_head {
                    if (*fixed_head.as_ptr()).left.is_none() {
                        (*fixed_head.as_ptr()).left = Node::new_black(value);
                        self.count += 1;
                        return true;
                    }

                    let parent = self.find_put_parent_candidate(self.get_root(), &value);

                    if let Some(parent) = parent {
                        if self.attach_node(parent, value) {
                            self.put_balancing(parent);
                        } else {
                            return false;
                        }
                    } else {
                        return false;
                    }
                } else {
                    self.fixed_head = Node::new_fixed_head(value);
                }

                self.count += 1;
                true
            }
        }

        /// Removes a value from the tree.
        ///
        /// Returns `true` if the value existed and was removed.
        ///
        /// Use [`RedBlackTree::take`] when ownership of the removed value is needed.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.insert(10);
        ///
        /// assert!(tree.remove(&10));
        /// assert!(!tree.contains(&10));
        /// assert!(!tree.remove(&10));
        /// ```
        pub fn remove(&mut self, value: &T) -> bool {
            self.take(value).is_some()
        }

        /// Inserts `value` into the tree, replacing an existing equal value.
        ///
        /// If the tree already contains a value that compares equal to `value`,
        /// the existing value is replaced and returned.
        ///
        /// If no equal value exists, `value` is inserted and `None` is returned.
        ///
        /// This is especially useful for custom types whose [`Ord`] implementation
        /// compares only a key field.
        ///
        /// # Examples
        ///
        /// ```
        /// use std::cmp::Ordering;
        /// use rbtree_extended::RedBlackTree;
        ///
        /// #[derive(Debug, Default)]
        /// struct User {
        ///     id: u32,
        ///     name: String,
        /// }
        ///
        /// impl PartialEq for User {
        ///     fn eq(&self, other: &Self) -> bool {
        ///         self.id == other.id
        ///     }
        /// }
        ///
        /// impl Eq for User {}
        ///
        /// impl PartialOrd for User {
        ///     fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        ///         Some(self.cmp(other))
        ///     }
        /// }
        ///
        /// impl Ord for User {
        ///     fn cmp(&self, other: &Self) -> Ordering {
        ///         self.id.cmp(&other.id)
        ///     }
        /// }
        ///
        /// let mut users = RedBlackTree::new();
        ///
        /// users.insert(User {
        ///     id: 1,
        ///     name: "Alice".into(),
        /// });
        ///
        /// let old = users.replace(User {
        ///     id: 1,
        ///     name: "Bob".into(),
        /// });
        ///
        /// assert_eq!(old.unwrap().name, "Alice");
        /// assert_eq!(users.first().unwrap().name, "Bob");
        /// ```
        pub fn replace(&mut self, value: T) -> Option<T> {
            unsafe {
                if let Some(mut node) = find_node(self.get_root(), &value) {
                    return Some(std::mem::replace(&mut node.as_mut().value, value));
                }
            }

            self.insert(value);

            None
        }

        unsafe fn take_node(&mut self, mut node: NonNull<Node<T>>) -> Option<T> {
            unsafe {
                // Save the original value before the internal removal algorithm
                // starts swapping values between nodes.
                let removed_value = std::mem::take(&mut node.as_mut().value);

                if !self.remove_node(node) {
                    return None;
                }

                self.count -= 1;

                Some(removed_value)
            }
        }

        /// Removes and returns the value equal to `value`.
        ///
        /// Returns `None` if the value is not present in the tree.
        ///
        /// Unlike [`RedBlackTree::remove`], this method gives ownership of the
        /// removed value back to the caller.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([10, 5, 20]);
        ///
        /// assert_eq!(tree.take(&10), Some(10));
        /// assert!(!tree.contains(&10));
        /// assert_eq!(tree.take(&100), None);
        /// ```
        pub fn take(&mut self, value: &T) -> Option<T> {
            if self.is_empty() {
                return None;
            }

            unsafe {
                let node = find_node(self.get_root(), value)?;
                self.take_node(node)
            }
        }

        /// Retains only the values specified by the predicate.
        ///
        /// In other words, removes every value for which `f(&value)` returns `false`.
        ///
        /// The predicate receives a shared reference to each stored value.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([1, 2, 3, 4, 5, 6]);
        ///
        /// tree.retain(|value| value % 2 == 0);
        ///
        /// assert_eq!(
        ///     tree.iter().copied().collect::<Vec<_>>(),
        ///     vec![2, 4, 6]
        /// );
        /// ```
        ///
        /// Retaining no values empties the tree:
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([1, 2, 3]);
        ///
        /// tree.retain(|_| false);
        ///
        /// assert!(tree.is_empty());
        /// ```
        pub fn retain<F>(&mut self, mut f: F)
        where
            F: FnMut(&T) -> bool,
        {
            let mut retained = Self::new();

            while let Some(value) = self.pop_first() {
                if f(&value) {
                    retained.insert(value);
                }
            }

            *self = retained;
        }

        /// Removes and returns the smallest value in the tree.
        ///
        /// Returns `None` if the tree is empty.
        ///
        /// This operation is useful when values need to be processed in
        /// ascending order.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([8, 3, 10, 1, 6]);
        ///
        /// assert_eq!(tree.pop_first(), Some(1));
        /// assert_eq!(tree.pop_first(), Some(3));
        /// assert_eq!(tree.len(), 3);
        /// ```
        pub fn pop_first(&mut self) -> Option<T> {
            unsafe {
                let root = self.get_root()?;
                let node = self.find_min(root);

                self.take_node(node)
            }
        }

        /// Removes and returns the largest value in the tree.
        ///
        /// Returns `None` if the tree is empty.
        ///
        /// This operation can be used to implement a priority queue where the
        /// greatest value represents the highest priority.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([8, 3, 10, 1, 6]);
        ///
        /// assert_eq!(tree.pop_last(), Some(10));
        /// assert_eq!(tree.pop_last(), Some(8));
        /// assert_eq!(tree.len(), 3);
        /// ```
        pub fn pop_last(&mut self) -> Option<T> {
            unsafe {
                let root = self.get_root()?;
                let node = self.find_max(root);

                self.take_node(node)
            }
        }

        /// Returns a reference to the stored value equal to `value`.
        ///
        /// Returns `None` if no matching value exists.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([1, 3, 5]);
        ///
        /// assert_eq!(tree.get(&3), Some(&3));
        /// assert_eq!(tree.get(&4), None);
        /// ```
        pub fn get(&self, value: &T) -> Option<&T> {
            unsafe {
                let node = find_node(self.get_root(), value)?;
                Some(&node.as_ref().value)
            }
        }

        /// Returns the next greater value in sorted order.
        ///
        /// Returns `None` if `value` is not present or if it is the largest value.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([1, 3, 5, 7]);
        ///
        /// assert_eq!(tree.successor(&3), Some(&5));
        /// assert_eq!(tree.successor(&7), None);
        /// ```
        pub fn successor(&self, value: &T) -> Option<&T> {
            unsafe {
                let node = find_node(self.get_root(), value)?;

                // Case 1:
                // there is a right subtree - successor = minimum element on the right
                if let Some(right) = node.as_ref().right {
                    let successor = self.find_min(right);
                    return Some(&successor.as_ref().value);
                }

                // Case 2:
                // there is no right subtree
                // Move up while the current node is a right child
                let mut current = node;
                let mut parent = current.as_ref().parent;

                while let Some(p) = parent {
                    if let Some(left) = p.as_ref().left
                        && std::ptr::eq(left.as_ptr(), current.as_ptr())
                    {
                        return Some(&p.as_ref().value);
                    }

                    current = p;
                    parent = p.as_ref().parent;
                }

                None
            }
        }

        /// Returns the previous smaller value in sorted order.
        ///
        /// Returns `None` if `value` is not present or if it is the smallest value.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([1, 3, 5, 7]);
        ///
        /// assert_eq!(tree.predecessor(&5), Some(&3));
        /// assert_eq!(tree.predecessor(&1), None);
        /// ```
        pub fn predecessor(&self, value: &T) -> Option<&T> {
            unsafe {
                let node = find_node(self.get_root(), value)?;

                // Case 1:
                // there is a left subtree - predecessor = maximum element on the left
                if let Some(left) = node.as_ref().left {
                    let predecessor = self.find_max(left);
                    return Some(&predecessor.as_ref().value);
                }

                // Case 2:
                // there is no left subtree
                // Move up while the current node is a left child
                let mut current = node;
                let mut parent = current.as_ref().parent;

                while let Some(p) = parent {
                    if let Some(right) = p.as_ref().right
                        && std::ptr::eq(right.as_ptr(), current.as_ptr())
                    {
                        return Some(&p.as_ref().value);
                    }

                    current = p;
                    parent = p.as_ref().parent;
                }

                None
            }
        }

        /// Returns the first value greater than or equal to `value`.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([1, 3, 6, 8]);
        ///
        /// assert_eq!(tree.lower_bound(&5), Some(&6));
        /// assert_eq!(tree.lower_bound(&6), Some(&6));
        /// ```
        pub fn lower_bound(&self, value: &T) -> Option<&T> {
            unsafe {
                let mut current = self.get_root();
                let mut candidate: Link<T> = None;

                while let Some(node) = current {
                    match node.as_ref().value.cmp(value) {
                        Ordering::Less => {
                            current = node.as_ref().right;
                        }

                        Ordering::Equal => {
                            return Some(&node.as_ref().value);
                        }

                        Ordering::Greater => {
                            candidate = Some(node);
                            current = node.as_ref().left;
                        }
                    }
                }

                candidate.map(|node| &node.as_ref().value)
            }
        }

        /// Returns the first value strictly greater than `value`.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([1, 3, 6, 8]);
        ///
        /// assert_eq!(tree.upper_bound(&6), Some(&8));
        /// assert_eq!(tree.upper_bound(&8), None);
        /// ```
        pub fn upper_bound(&self, value: &T) -> Option<&T> {
            unsafe {
                let mut current = self.get_root();
                let mut candidate: Link<T> = None;

                while let Some(node) = current {
                    match node.as_ref().value.cmp(value) {
                        Ordering::Less | Ordering::Equal => {
                            current = node.as_ref().right;
                        }
                        Ordering::Greater => {
                            candidate = Some(node);
                            current = node.as_ref().left;
                        }
                    }
                }

                candidate.map(|node| &node.as_ref().value)
            }
        }

        /// Returns an iterator over values in the inclusive range `[min, max]`.
        ///
        /// Values are yielded in ascending order.
        ///
        /// The iterator is lazy: values are produced only as they are requested,
        /// rather than being collected into an intermediate `Vec`.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([1, 3, 5, 7, 9, 11]);
        ///
        /// let values: Vec<_> = tree
        ///     .range(&3, &9)
        ///     .copied()
        ///     .collect();
        ///
        /// assert_eq!(values, vec![3, 5, 7, 9]);
        /// ```
        pub fn range(&self, min: &T, max: &T) -> Range<'_, T> {
            Range::new(self.get_root(), min, max)
        }

        /// Returns the next value in an in-order (`LNR`) traversal.
        ///
        /// For a binary search tree, in-order traversal visits values in ascending order.
        ///
        /// Returns `None` if `value` is not present or has no successor in this traversal.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([4, 2, 6, 1, 3, 5, 7]);
        ///
        /// assert_eq!(tree.successor_dfs_in_order(4), Some(&5));
        /// ```
        pub fn successor_dfs_in_order(&self, value: T) -> Option<&T> {
            unsafe {
                let node = find_node(self.get_root(), &value);
                if let Some(n) = node
                    && let Some(nodesucc) = successor_of_node_in_order(n)
                {
                    return Some(&nodesucc.as_ref().value);
                }
                None
            }
        }

        /// Returns the next value in reverse in-order (`RNL`) traversal.
        ///
        /// For a binary search tree, reverse in-order traversal visits values in
        /// descending order.
        ///
        /// Returns `None` if `value` is not present or has no successor in this traversal.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([4, 2, 6, 1, 3, 5, 7]);
        ///
        /// assert_eq!(tree.successor_dfs_reverse_in_order(6), Some(&5));
        /// ```
        pub fn successor_dfs_reverse_in_order(&self, value: T) -> Option<&T> {
            unsafe {
                if let Some(node) = find_node(self.get_root(), &value)
                    && let Some(next) = successor_of_node_reverse_in_order(node)
                {
                    return Some(&next.as_ref().value);
                }
                None
            }
        }

        /// Returns the next value in post-order (`LRN`) traversal.
        ///
        /// Post-order visits the left subtree, then the right subtree,
        /// and finally the current node.
        ///
        /// Returns `None` if `value` is not present or has no successor in this traversal.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([4, 2, 6, 1, 3, 5, 7]);
        ///
        /// // Post-order: 1, 3, 2, 5, 7, 6, 4
        /// assert_eq!(tree.successor_dfs_post_order(3), Some(&2));
        /// assert_eq!(tree.successor_dfs_post_order(2), Some(&5));
        /// assert_eq!(tree.successor_dfs_post_order(4), None);
        /// ```
        pub fn successor_dfs_post_order(&self, value: T) -> Option<&T> {
            unsafe {
                if let Some(n) = find_node(self.get_root(), &value)
                    && let Some(nodesucc) = successor_of_node_post_order(n)
                {
                    return Some(&nodesucc.as_ref().value);
                }
                None
            }
        }

        /// Returns the next value in pre-order (`NLR`) traversal.
        ///
        /// Pre-order visits the current node first, followed by the left and right
        /// subtrees.
        ///
        /// Returns `None` if `value` is not present or has no successor in this traversal.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([4, 2, 6, 1, 3, 5, 7]);
        ///
        /// let first = *tree.iter_preorder().next().unwrap();
        /// assert_eq!(tree.successor_dfs_pre_order(first), tree.iter_preorder().nth(1));
        /// ```
        pub fn successor_dfs_pre_order(&self, value: T) -> Option<&T> {
            unsafe {
                if let Some(n) = find_node(self.get_root(), &value)
                    && let Some(nodesucc) = successor_of_node_pre_order(n)
                {
                    return Some(&nodesucc.as_ref().value);
                }
                None
            }
        }

        fn get_root(&self) -> Link<T> {
            if let Some(fixed_head) = self.fixed_head {
                unsafe { (*fixed_head.as_ptr()).left }
            } else {
                None
            }
        }

        unsafe fn operation_remove(&self, node_x: &NonNull<Node<T>>) -> OperationRemove {
            unsafe {
                if node_x.as_ref().is_red
                    && node_x.as_ref().left.is_none()
                    && node_x.as_ref().right.is_none()
                {
                    return OperationRemove::RedLeaf;
                }
                if node_x.as_ref().is_red
                    && node_x.as_ref().left.is_some()
                    && node_x.as_ref().right.is_some()
                {
                    return OperationRemove::NodeWithChildren;
                }
                if !node_x.as_ref().is_red {
                    if node_x.as_ref().left.is_some() && node_x.as_ref().right.is_some() {
                        return OperationRemove::NodeWithChildren;
                    } else if node_x.as_ref().left.is_some() && node_x.as_ref().right.is_none() {
                        if let Some(left) = node_x.as_ref().left
                            && left.as_ref().is_red
                            && left.as_ref().left.is_none()
                            && left.as_ref().right.is_none()
                        {
                            return OperationRemove::BlackNodeWithRedLeaf;
                        }
                    } else if node_x.as_ref().left.is_none() && node_x.as_ref().right.is_none() {
                        return OperationRemove::BlackLeaf;
                    }
                }
                panic!();
            }
        }

        unsafe fn operation_remove_black_leaf(
            &self,
            node_x: &NonNull<Node<T>>,
        ) -> OperationRemoveBlackLeaf {
            unsafe {
                if let Some(node_a) = node_x.as_ref().parent {
                    if node_a.as_ref().is_red {
                        if let Some(node_b) = node_a.as_ref().left
                            && !std::ptr::eq(node_b.as_ptr(), node_x.as_ptr())
                            && !node_b.as_ref().is_red
                        {
                            if let Some(node_c) = node_b.as_ref().left
                                && node_c.as_ref().is_red
                            {
                                return OperationRemoveBlackLeaf::LeftRedABlackBRedCleaf;
                                // 2.1.1.1
                            }

                            // sibling B is black and its left child is either absent or also black
                            return OperationRemoveBlackLeaf::LeftRedABlackBleaf;
                            // 2.1.2.1
                        }

                        if let Some(node_b) = node_a.as_ref().right
                            && !std::ptr::eq(node_b.as_ptr(), node_x.as_ptr())
                            && !node_b.as_ref().is_red
                        {
                            if let Some(node_c) = node_b.as_ref().left
                                && node_c.as_ref().is_red
                            {
                                return OperationRemoveBlackLeaf::RightRedABlackBRedCleaf;
                                // 2.1.1.2
                            }

                            // sibling B is black and its left child is either absent or also black
                            return OperationRemoveBlackLeaf::RightRedABlackBleaf;
                            // 2.1.2.2
                        }
                    } else {
                        if let Some(node_b) = node_a.as_ref().left
                            && !std::ptr::eq(node_b.as_ptr(), node_x.as_ptr())
                        {
                            if node_b.as_ref().is_red && node_b.as_ref().right.is_some() {
                                let node_c = node_b.as_ref().right.unwrap();
                                if !node_c.as_ref().is_red {
                                    if node_c.as_ref().left.is_some()
                                        && let Some(node_d) = node_c.as_ref().left
                                        && node_d.as_ref().is_red
                                    {
                                        return OperationRemoveBlackLeaf::BlackARedBWithBlackChildrenRightHaveRedLeaf;
                                        // 2.2.1
                                    }
                                    return OperationRemoveBlackLeaf::BlackARedBWithBlackChildrenLeaf;
                                    // 2.2.2
                                }
                            }
                            if !node_b.as_ref().is_red
                                && node_b.as_ref().left.is_some()
                                && let Some(node_d) = node_b.as_ref().left
                                && node_d.as_ref().is_red
                            {
                                return OperationRemoveBlackLeaf::BlackALeftBlackBRedDleaf;
                                // 2.3.1.1
                            }
                            if !node_b.as_ref().is_red {
                                return OperationRemoveBlackLeaf::BlackALeftBlackBleaf;
                                // 2.3.2.1
                            }
                        }
                        if let Some(node_b) = node_a.as_ref().right
                            && !std::ptr::eq(node_b.as_ptr(), node_x.as_ptr())
                        {
                            if !node_b.as_ref().is_red
                                && node_b.as_ref().left.is_some()
                                && let Some(node_d) = node_b.as_ref().left
                                && node_d.as_ref().is_red
                            {
                                return OperationRemoveBlackLeaf::BlackARightBlackBRedDleaf;
                                // 2.3.1.2
                            }
                            if !node_b.as_ref().is_red {
                                return OperationRemoveBlackLeaf::BlackARightBlackBleaf;
                                // 2.3.2.2
                            }
                        }
                    }
                } else {
                    return OperationRemoveBlackLeaf::Root;
                }
                OperationRemoveBlackLeaf::Unimplemented
            }
        }

        unsafe fn remove_black_leaf(&mut self, node_x: NonNull<Node<T>>) -> bool {
            unsafe {
                let mut next = node_x;
                let mut removed = false;
                loop {
                    match self.operation_remove_black_leaf(&next) {
                        OperationRemoveBlackLeaf::LeftRedABlackBRedCleaf => {
                            self.remove_black_leaf_2_1_1_1_balancing(&next);
                            if !removed {
                                removed = self.remove_leaf(node_x);
                            }
                            break;
                        }
                        OperationRemoveBlackLeaf::RightRedABlackBRedCleaf => {
                            self.remove_black_leaf_2_1_1_2_balancing(&next);
                            if !removed {
                                removed = self.remove_leaf(node_x);
                            }
                            break;
                        }
                        OperationRemoveBlackLeaf::LeftRedABlackBleaf => {
                            self.remove_black_leaf_2_1_2_1_balancing(&next);
                            if !removed {
                                removed = self.remove_leaf(node_x);
                            }
                            break;
                        }
                        OperationRemoveBlackLeaf::RightRedABlackBleaf => {
                            self.remove_black_leaf_2_1_2_2_balancing(&next);
                            if !removed {
                                removed = self.remove_leaf(node_x);
                            }
                            break;
                        }
                        OperationRemoveBlackLeaf::BlackARedBWithBlackChildrenRightHaveRedLeaf => {
                            self.remove_black_leaf_2_2_1_balancing(&next);
                            if !removed {
                                removed = self.remove_leaf(node_x);
                            }
                            break;
                        }
                        OperationRemoveBlackLeaf::BlackARedBWithBlackChildrenLeaf => {
                            self.remove_black_leaf_2_2_2_balancing(&next);
                            if !removed {
                                removed = self.remove_leaf(node_x);
                            }
                            break;
                        }
                        OperationRemoveBlackLeaf::BlackALeftBlackBRedDleaf => {
                            self.remove_black_leaf_2_3_1_1_balancing(&next);
                            if !removed {
                                removed = self.remove_leaf(node_x);
                            }
                            break;
                        }
                        OperationRemoveBlackLeaf::BlackARightBlackBRedDleaf => {
                            self.remove_black_leaf_2_3_1_2_balancing(&next);
                            if !removed {
                                removed = self.remove_leaf(node_x);
                            }
                            break;
                        }
                        OperationRemoveBlackLeaf::BlackALeftBlackBleaf => {
                            next = self.remove_black_leaf_2_3_2_1_balancing(&next);
                            if !removed {
                                removed = self.remove_leaf(node_x);
                            }
                        }
                        OperationRemoveBlackLeaf::BlackARightBlackBleaf => {
                            next = self.remove_black_leaf_2_3_2_2_balancing(&next);
                            if !removed {
                                removed = self.remove_leaf(node_x);
                            }
                        }
                        OperationRemoveBlackLeaf::Root => {
                            if !removed {
                                // We get here when the node_x being deleted is root
                                if let Some(fixed_head) = self.fixed_head {
                                    (*fixed_head.as_ptr()).left = None;
                                }
                                let _ = Box::from_raw(node_x.as_ptr());
                                removed = true;
                            }
                            break;
                        }
                        OperationRemoveBlackLeaf::Unimplemented => {
                            panic!("unimplemented black leaf removal case");
                        }
                    }
                }
                removed
            }
        }

        /// 2.1.1.1 remove black X
        ///
        /// ```text
        ///             P            P
        ///            //           //
        ///            A            B
        ///           / \          / \
        ///          B   X   =>   C   A
        ///         //\              /
        ///        C   D            D
        /// ```
        unsafe fn remove_black_leaf_2_1_1_1_balancing(&mut self, node_x: &NonNull<Node<T>>) {
            unsafe {
                let node_a = (*node_x.as_ptr()).parent.unwrap();
                let node_b = (*node_a.as_ptr()).left.unwrap();
                let node_d = (*node_b.as_ptr()).right;
                (*node_b.as_ptr()).parent = (*node_a.as_ptr()).parent;
                if let Some(ref mut parent) = (*node_b.as_ptr()).parent {
                    (*parent.as_ptr()).left = Some(node_b);
                }
                (*node_a.as_ptr()).left = node_d;
                if let Some(n_d) = node_d {
                    (*n_d.as_ptr()).parent = Some(node_a);
                }
                (*node_a.as_ptr()).is_red = false;
                (*node_b.as_ptr()).right = Some(node_a);
                (*node_a.as_ptr()).parent = Some(node_b);
                (*node_b.as_ptr()).is_red = true;
                if let Some(node_c) = (*node_b.as_ptr()).left {
                    (*node_c.as_ptr()).is_red = false;
                }
            }
        }

        /// 2.1.1.2 remove black X
        ///
        /// ```text
        ///             P              P
        ///            //             //
        ///           A               C
        ///          / \            /   \
        ///         X   B   =>     A     B
        ///            //           \   /
        ///            C             E D
        ///           / \
        ///          E   D
        /// ```
        unsafe fn remove_black_leaf_2_1_1_2_balancing(&mut self, node_x: &NonNull<Node<T>>) {
            unsafe {
                let node_a = (*node_x.as_ptr()).parent.unwrap();
                (*node_a.as_ptr()).is_red = false;
                let parent: NonNull<Node<T>> = (*node_a.as_ptr()).parent.unwrap();
                let node_b = (*node_a.as_ptr()).right.unwrap();
                let node_c = (*node_b.as_ptr()).left.unwrap();
                let node_e = (*node_c.as_ptr()).left;
                let node_d = (*node_c.as_ptr()).right;
                (*parent.as_ptr()).left = Some(node_c);
                (*node_c.as_ptr()).parent = Some(parent);
                (*node_b.as_ptr()).left = node_d;
                if let Some(n_d) = node_d {
                    (*n_d.as_ptr()).parent = Some(node_b);
                }
                (*node_c.as_ptr()).right = Some(node_b);
                (*node_b.as_ptr()).parent = Some(node_c);
                (*node_c.as_ptr()).left = Some(node_a);
                (*node_a.as_ptr()).parent = Some(node_c);
                (*node_a.as_ptr()).right = node_e;
                if let Some(n_e) = node_e {
                    (*n_e.as_ptr()).parent = Some(node_a);
                }
            }
        }

        /// 2.1.2.1 remove black X
        ///
        /// ```text
        ///              P            P
        ///             //           /
        ///            A            A
        ///           / \          //
        ///          B   X   =>   B
        ///
        /// ```
        unsafe fn remove_black_leaf_2_1_2_1_balancing(&mut self, node_x: &NonNull<Node<T>>) {
            unsafe {
                let node_a = (*node_x.as_ptr()).parent.unwrap();
                (*node_a.as_ptr()).is_red = false;
                if let Some(node_b) = (*node_a.as_ptr()).left {
                    (*node_b.as_ptr()).is_red = true;
                }
            }
        }

        /// 2.1.2.2 remove black X
        ///
        /// ```text
        ///             P            P
        ///            //           /
        ///            A     =>     B
        ///           / \          //\
        ///          X   B        A   D
        ///             / \        \
        ///            C   D        C
        /// ```
        unsafe fn remove_black_leaf_2_1_2_2_balancing(&mut self, node_x: &NonNull<Node<T>>) {
            unsafe {
                let node_a = (*node_x.as_ptr()).parent.unwrap();
                let node_b = (*node_a.as_ptr()).right.unwrap();
                let node_c = (*node_b.as_ptr()).left;
                let node_d = (*node_b.as_ptr()).right;
                let parent = (*node_a.as_ptr()).parent.unwrap();
                if let Some(left) = (*parent.as_ptr()).left {
                    if std::ptr::eq(node_a.as_ptr(), left.as_ptr()) {
                        (*parent.as_ptr()).left = Some(node_b);
                    } else {
                        (*parent.as_ptr()).right = Some(node_b);
                    }
                } else {
                    (*parent.as_ptr()).right = Some(node_b);
                }
                (*node_b.as_ptr()).parent = Some(parent);
                (*node_b.as_ptr()).left = Some(node_a);
                (*node_b.as_ptr()).right = node_d;
                if let Some(n_d) = node_d {
                    (*n_d.as_ptr()).parent = Some(node_b);
                }
                (*node_a.as_ptr()).parent = Some(node_b);
                (*node_a.as_ptr()).right = node_c;
                if let Some(n_c) = node_c {
                    (*n_c.as_ptr()).parent = Some(node_a);
                }
            }
        }

        /// 2.2.1 remove black X
        ///
        /// ```text
        ///            A               C
        ///          // \            //  \
        ///         B    X    =>    B     A
        ///          \               \   /
        ///           C               D E
        ///           //\
        ///          D   E
        /// ```
        unsafe fn remove_black_leaf_2_2_1_balancing(&mut self, node_x: &NonNull<Node<T>>) {
            unsafe {
                let n_a = node_x.as_ref().parent.unwrap();
                if n_a.as_ref().parent.is_some() {
                    let parent = (*n_a.as_ptr()).parent.unwrap();
                    let mut node_a_from_left = false;
                    if let Some(ref mut node_a) = (*parent.as_ptr()).left
                        && std::ptr::eq(node_a.as_ptr(), n_a.as_ptr())
                    {
                        node_a_from_left = true;
                    }
                    let node_a = if node_a_from_left {
                        (*parent.as_ptr()).left.unwrap()
                    } else {
                        (*parent.as_ptr()).right.unwrap()
                    };
                    let node_b = (*node_a.as_ptr()).left.unwrap();
                    let node_c = (*node_b.as_ptr()).right.unwrap();
                    let node_e = (*node_c.as_ptr()).right;
                    let node_d = (*node_c.as_ptr()).left.unwrap();
                    (*node_b.as_ptr()).right = Some(node_d);
                    (*node_b.as_ptr()).parent = Some(node_c);
                    (*node_d.as_ptr()).parent = Some(node_b);
                    (*node_a.as_ptr()).parent = Some(node_c);
                    (*node_a.as_ptr()).left = node_e;
                    if let Some(n_e) = node_e {
                        (*n_e.as_ptr()).parent = Some(node_a);
                    }
                    (*node_d.as_ptr()).is_red = false;
                    (*node_c.as_ptr()).left = Some(node_b);
                    (*node_c.as_ptr()).right = Some(node_a);
                    (*node_c.as_ptr()).parent = Some(parent);
                    if node_a_from_left {
                        (*parent.as_ptr()).left = Some(node_c);
                    } else {
                        (*parent.as_ptr()).right = Some(node_c);
                    }
                } else {
                    // node_a is root
                    if let Some(fixed_head) = self.fixed_head {
                        let node_a = (*fixed_head.as_ptr()).left.unwrap();
                        let node_b = (*node_a.as_ptr()).left.unwrap();
                        let node_c = (*node_b.as_ptr()).right.unwrap();
                        let node_e = (*node_c.as_ptr()).right;
                        let node_d = (*node_c.as_ptr()).left.unwrap();
                        (*node_b.as_ptr()).right = Some(node_d);
                        (*node_b.as_ptr()).parent = Some(node_c);
                        (*node_d.as_ptr()).parent = Some(node_b);
                        (*node_a.as_ptr()).parent = Some(node_c);
                        (*node_a.as_ptr()).left = node_e;
                        if let Some(n_e) = node_e {
                            (*n_e.as_ptr()).parent = Some(node_a);
                        }
                        (*node_d.as_ptr()).is_red = false;
                        (*node_c.as_ptr()).left = Some(node_b);
                        (*node_c.as_ptr()).right = Some(node_a);
                        (*node_c.as_ptr()).parent = None;
                        (*fixed_head.as_ptr()).left = Some(node_c);
                    }
                }
            }
        }

        /// 2.2.2 remove black X
        ///
        /// ```text
        ///    A            B
        ///  // \            \
        ///  B    X   =>       A
        ///  \               //
        ///   C             C
        /// ```
        unsafe fn remove_black_leaf_2_2_2_balancing(&mut self, node_x: &NonNull<Node<T>>) {
            unsafe {
                let n_a = node_x.as_ref().parent.unwrap();
                if n_a.as_ref().parent.is_some() {
                    let parent = (*n_a.as_ptr()).parent.unwrap();
                    let mut node_a_from_left = false;
                    if let Some(ref mut node_a) = (*parent.as_ptr()).left
                        && std::ptr::eq(node_a.as_ptr(), n_a.as_ptr())
                    {
                        node_a_from_left = true;
                    }
                    let node_a = if node_a_from_left {
                        (*parent.as_ptr()).left.unwrap()
                    } else {
                        (*parent.as_ptr()).right.unwrap()
                    };
                    let node_b = (*node_a.as_ptr()).left.unwrap();
                    (*node_b.as_ptr()).is_red = false;
                    (*node_b.as_ptr()).parent = Some(parent);
                    let node_c = (*node_b.as_ptr()).right.unwrap();
                    (*node_c.as_ptr()).is_red = true;
                    (*node_b.as_ptr()).right = Some(node_a);
                    (*node_a.as_ptr()).left = Some(node_c);
                    (*node_c.as_ptr()).parent = Some(node_a);
                    (*node_a.as_ptr()).parent = Some(node_b);
                    if node_a_from_left {
                        (*parent.as_ptr()).left = Some(node_b);
                    } else {
                        (*parent.as_ptr()).right = Some(node_b);
                    }
                } else {
                    // node_a is root
                    if let Some(fixed_head) = self.fixed_head {
                        let node_a = (*fixed_head.as_ptr()).left.unwrap();
                        let node_b = (*node_a.as_ptr()).left.unwrap();
                        (*node_b.as_ptr()).is_red = false;
                        (*node_b.as_ptr()).parent = None;
                        let node_c = (*node_b.as_ptr()).right.unwrap();
                        (*node_c.as_ptr()).is_red = true;
                        (*node_b.as_ptr()).right = Some(node_a);
                        (*node_a.as_ptr()).left = Some(node_c);
                        (*node_c.as_ptr()).parent = Some(node_a);
                        (*node_a.as_ptr()).parent = Some(node_b);
                        (*fixed_head.as_ptr()).left = Some(node_b);
                    }
                }
            }
        }

        /// 2.3.1.1 remove black X
        ///
        /// ```text
        ///      A           B
        ///     / \         / \
        ///    B   X  =>   D   A
        ///   // \            /
        ///  D    C          C
        /// ```
        unsafe fn remove_black_leaf_2_3_1_1_balancing(&mut self, node_x: &NonNull<Node<T>>) {
            unsafe {
                let node_a = (*node_x.as_ptr()).parent.unwrap();
                if let Some(parent) = (*node_a.as_ptr()).parent {
                    let node_b = (*node_a.as_ptr()).left.unwrap();
                    let node_c = (*node_b.as_ptr()).right;
                    let node_d = (*node_b.as_ptr()).left.unwrap();
                    (*node_d.as_ptr()).is_red = false;
                    let mut node_a_from_left = false;
                    if let Some(p_node_a) = (*parent.as_ptr()).left
                        && std::ptr::eq(p_node_a.as_ptr(), node_a.as_ptr())
                    {
                        node_a_from_left = true;
                    }
                    (*node_b.as_ptr()).parent = Some(parent);
                    (*node_b.as_ptr()).right = Some(node_a);
                    (*node_a.as_ptr()).parent = Some(node_b);
                    (*node_a.as_ptr()).left = node_c;
                    if let Some(n_c) = node_c {
                        (*n_c.as_ptr()).parent = Some(node_a);
                    }
                    if node_a_from_left {
                        (*parent.as_ptr()).left = Some(node_b);
                    } else {
                        (*parent.as_ptr()).right = Some(node_b);
                    }
                } else {
                    // node_a is root
                    if let Some(fixed_head) = self.fixed_head {
                        let node_a = (*fixed_head.as_ptr()).left.unwrap();
                        let node_b = (*node_a.as_ptr()).left.unwrap();
                        let node_c = (*node_b.as_ptr()).right;
                        let node_d = (*node_b.as_ptr()).left.unwrap();
                        (*node_d.as_ptr()).is_red = false;
                        let node_b = (*node_a.as_ptr()).left.unwrap();
                        (*node_b.as_ptr()).parent = None;
                        (*node_b.as_ptr()).right = Some(node_a);
                        (*node_a.as_ptr()).parent = Some(node_b);
                        (*node_a.as_ptr()).left = node_c;
                        if let Some(n_c) = node_c {
                            (*n_c.as_ptr()).parent = Some(node_a);
                        }
                        (*fixed_head.as_ptr()).left = Some(node_b);
                    }
                }
            }
        }

        /// 2.3.1.2 remove black X
        ///
        /// ```text
        ///
        ///      A            D
        ///     / \         /   \
        ///    X   B  =>   A     B
        ///       //        \   /
        ///       D          C E
        ///      / \
        ///     C   E
        /// ```
        unsafe fn remove_black_leaf_2_3_1_2_balancing(&mut self, node_x: &NonNull<Node<T>>) {
            unsafe {
                let node_a = (*node_x.as_ptr()).parent.unwrap();
                if let Some(parent) = (*node_a.as_ptr()).parent {
                    let node_b = (*node_a.as_ptr()).right.unwrap();
                    let node_d = (*node_b.as_ptr()).left.unwrap();
                    let node_c = (*node_d.as_ptr()).left;
                    let node_e = (*node_d.as_ptr()).right;
                    (*node_d.as_ptr()).is_red = false;
                    let mut node_a_from_left = false;
                    if let Some(p_node_a) = (*parent.as_ptr()).left
                        && std::ptr::eq(p_node_a.as_ptr(), node_a.as_ptr())
                    {
                        node_a_from_left = true;
                    }
                    (*node_d.as_ptr()).parent = Some(parent);
                    (*node_d.as_ptr()).left = Some(node_a);
                    (*node_d.as_ptr()).right = Some(node_b);
                    (*node_a.as_ptr()).parent = Some(node_d);
                    (*node_b.as_ptr()).parent = Some(node_d);
                    (*node_a.as_ptr()).right = node_c;
                    if let Some(n_c) = node_c {
                        (*n_c.as_ptr()).parent = Some(node_a);
                    }
                    (*node_b.as_ptr()).left = node_e;
                    if let Some(n_e) = node_e {
                        (*n_e.as_ptr()).parent = Some(node_b);
                    }
                    if node_a_from_left {
                        (*parent.as_ptr()).left = Some(node_d);
                    } else {
                        (*parent.as_ptr()).right = Some(node_d);
                    }
                } else {
                    // node_a is root
                    if let Some(fixed_head) = self.fixed_head {
                        let node_a = (*fixed_head.as_ptr()).left.unwrap();
                        let node_b = (*node_a.as_ptr()).right.unwrap();
                        let node_d = (*node_b.as_ptr()).left.unwrap();
                        let node_c = (*node_d.as_ptr()).left;
                        let node_e = (*node_d.as_ptr()).right;
                        (*node_d.as_ptr()).is_red = false;
                        (*node_d.as_ptr()).parent = None;
                        (*node_d.as_ptr()).left = Some(node_a);
                        (*node_d.as_ptr()).right = Some(node_b);
                        (*node_a.as_ptr()).parent = Some(node_d);
                        (*node_b.as_ptr()).parent = Some(node_d);
                        (*node_a.as_ptr()).right = node_c;
                        if let Some(n_c) = node_c {
                            (*n_c.as_ptr()).parent = Some(node_a);
                        }
                        (*node_b.as_ptr()).left = node_e;
                        if let Some(n_e) = node_e {
                            (*n_e.as_ptr()).parent = Some(node_b);
                        }
                        (*fixed_head.as_ptr()).left = Some(node_d);
                    }
                }
            }
        }

        /// 2.3.2.1 remove black X
        ///
        /// ```text
        ///            P           P
        ///            |           |
        ///            A           A
        ///           / \   =>    //   => next check node A
        ///          B   X       B
        ///
        /// ```
        unsafe fn remove_black_leaf_2_3_2_1_balancing(
            &mut self,
            node_x: &NonNull<Node<T>>,
        ) -> NonNull<Node<T>> {
            unsafe {
                let node_a = (*node_x.as_ptr()).parent.unwrap();
                let node_b = (*node_a.as_ptr()).left.unwrap();
                (*node_b.as_ptr()).is_red = true;
                node_a
            }
        }

        /// 2.3.2.2 remove black X
        ///
        /// ```text
        ///              A            B
        ///             / \   =>    // \    =>  next check node B
        ///            X   B       A    D
        ///               / \       \
        ///              C   D       C
        /// ```
        unsafe fn remove_black_leaf_2_3_2_2_balancing(
            &mut self,
            node_x: &NonNull<Node<T>>,
        ) -> NonNull<Node<T>> {
            unsafe {
                let node_a = (*node_x.as_ptr()).parent.unwrap();
                (*node_a.as_ptr()).is_red = true;
                if let Some(parent) = (*node_a.as_ptr()).parent {
                    let node_b = (*node_a.as_ptr()).right.unwrap();
                    let node_c = (*node_b.as_ptr()).left;
                    let node_d = (*node_b.as_ptr()).right;
                    let mut node_a_from_left = false;
                    if let Some(p_node_a) = (*parent.as_ptr()).left
                        && std::ptr::eq(p_node_a.as_ptr(), node_a.as_ptr())
                    {
                        node_a_from_left = true;
                    }
                    (*node_b.as_ptr()).parent = Some(parent);
                    (*node_a.as_ptr()).right = node_c;
                    if let Some(n_c) = node_c {
                        (*n_c.as_ptr()).parent = Some(node_a);
                    }
                    (*node_b.as_ptr()).right = node_d;
                    if let Some(n_d) = node_d {
                        (*n_d.as_ptr()).parent = Some(node_b);
                    }
                    (*node_b.as_ptr()).left = Some(node_a);
                    (*node_a.as_ptr()).parent = Some(node_b);
                    if node_a_from_left {
                        (*parent.as_ptr()).left = Some(node_b);
                    } else {
                        (*parent.as_ptr()).right = Some(node_b);
                    }
                    node_b
                } else {
                    // node_a is root
                    if let Some(fixed_head) = self.fixed_head {
                        let node_a = (*fixed_head.as_ptr()).left.unwrap();
                        (*node_a.as_ptr()).is_red = true;
                        let node_b = (*node_a.as_ptr()).right.unwrap();
                        let node_c = (*node_b.as_ptr()).left;
                        let node_d = (*node_b.as_ptr()).right;
                        (*node_b.as_ptr()).parent = None;
                        (*node_a.as_ptr()).right = node_c;
                        if let Some(n_c) = node_c {
                            (*n_c.as_ptr()).parent = Some(node_a);
                        }
                        (*node_b.as_ptr()).right = node_d;
                        if let Some(n_d) = node_d {
                            (*n_d.as_ptr()).parent = Some(node_b);
                        }
                        (*node_b.as_ptr()).left = Some(node_a);
                        (*node_a.as_ptr()).parent = Some(node_b);
                        (*fixed_head.as_ptr()).left = Some(node_b);
                    }
                    self.get_root().unwrap()
                }
            }
        }

        unsafe fn remove_node(&mut self, node: NonNull<Node<T>>) -> bool {
            unsafe {
                match self.operation_remove(&node) {
                    OperationRemove::RedLeaf => {
                        // option 1.0.0
                        //
                        // ```text
                        //
                        //  P
                        //  ||
                        //  X
                        //
                        // ```

                        self.remove_leaf(node)
                    }
                    OperationRemove::BlackLeaf => {
                        // option 2 black leaf
                        self.remove_black_leaf(node)
                    }
                    OperationRemove::NodeWithChildren => {
                        // option 4.0.0
                        // ```text
                        //        X
                        //     /      \
                        //    L        R
                        //   / \      / \
                        // ...  C    L
                        //          /
                        //         C
                        //        ...
                        //
                        // ```
                        /*
                            The node has two children.

                            We take the predecessor:
                            the maximal node of the left subtree.

                            We only change the values,
                            then we delete the predecessor as a regular node.
                        */

                        let predecessor = self.find_max(node.as_ref().left.unwrap());

                        std::mem::swap(
                            &mut (*node.as_ptr()).value,
                            &mut (*predecessor.as_ptr()).value,
                        );

                        self.remove_node(predecessor)
                    }
                    OperationRemove::BlackNodeWithRedLeaf => {
                        // option 3.0.0
                        // ```text
                        //  X
                        // //
                        // A
                        // ```
                        let red_left = (*node.as_ptr()).left.unwrap();
                        std::mem::swap(&mut (*node.as_ptr()).value, &mut (*red_left.as_ptr()).value);
                        self.remove_leaf(red_left)
                    }
                }
            }
        }

        unsafe fn find_max(&self, node: NonNull<Node<T>>) -> NonNull<Node<T>> {
            unsafe {
                if node.as_ref().right.is_some() {
                    self.find_max(node.as_ref().right.unwrap())
                } else {
                    node
                }
            }
        }

        unsafe fn find_min(&self, node: NonNull<Node<T>>) -> NonNull<Node<T>> {
            unsafe {
                if node.as_ref().left.is_some() {
                    self.find_min(node.as_ref().left.unwrap())
                } else {
                    node
                }
            }
        }

        unsafe fn remove_leaf(&mut self, node: NonNull<Node<T>>) -> bool {
            unsafe {
                if let Some(mut parent) = node.as_ref().parent {
                    if let Some(ref mut left) = parent.as_mut().left {
                        if std::ptr::eq(left.as_ptr(), node.as_ptr()) {
                            parent.as_mut().left = None;
                        } else {
                            parent.as_mut().right = None;
                        }
                    } else {
                        parent.as_mut().right = None;
                    }
                }
                let _ = Box::from_raw(node.as_ptr());
                true
            }
        }

        unsafe fn remove_tree(&mut self, node: Link<T>) {
            unsafe {
                if let Some(node) = node {
                    self.remove_tree(node.as_ref().left);
                    self.remove_tree(node.as_ref().right);
                    if self.remove_leaf(node) {
                        assert!(self.count > 0);
                        self.count -= 1;
                    }
                }
            }
        }

        /// Rotate left and Rotate right and Flip color
        ///
        /// ```text
        ///             |              ||
        ///             P              C
        ///           //  \          /   \
        ///          A     F        A     P
        ///         / \\      =>   / \   / \
        ///        B   C          B   E D   F
        ///            / \
        ///           E   D
        /// ```
        unsafe fn rotate_left_right_flip_color(&mut self, node_a: NonNull<Node<T>>) -> Link<T> {
            unsafe {
                let node_p = (*node_a.as_ptr()).parent.unwrap();
                if let Some(parent) = (*node_p.as_ptr()).parent {
                    let mut node_p_from_left = false;
                    if let Some(p_node_p) = (*parent.as_ptr()).left
                        && std::ptr::eq(p_node_p.as_ptr(), node_p.as_ptr())
                    {
                        node_p_from_left = true;
                    }
                    let node_p = if node_p_from_left {
                        (*parent.as_ptr()).left.unwrap()
                    } else {
                        (*parent.as_ptr()).right.unwrap()
                    };
                    (*node_a.as_ptr()).is_red = false;
                    let node_c = (*node_a.as_ptr()).right.unwrap();
                    (*node_c.as_ptr()).is_red = false;
                    let node_e = (*node_c.as_ptr()).left;
                    let node_d = (*node_c.as_ptr()).right;
                    (*node_c.as_ptr()).is_red = true;
                    (*node_c.as_ptr()).parent = Some(parent);
                    (*node_c.as_ptr()).left = Some(node_a);
                    (*node_a.as_ptr()).parent = Some(node_c);
                    (*node_c.as_ptr()).right = Some(node_p);
                    (*node_p.as_ptr()).parent = Some(node_c);
                    (*node_p.as_ptr()).left = node_d;
                    if let Some(n_d) = node_d {
                        (*n_d.as_ptr()).parent = Some(node_p);
                    }
                    (*node_a.as_ptr()).right = node_e;
                    if let Some(n_e) = node_e {
                        (*n_e.as_ptr()).parent = Some(node_a);
                    }
                    if node_p_from_left {
                        (*parent.as_ptr()).left = Some(node_c);
                    } else {
                        (*parent.as_ptr()).right = Some(node_c);
                    }
                    Some(parent)
                } else {
                    let fixed_head = self.fixed_head.unwrap();
                    let node_p = (*fixed_head.as_ptr()).left.unwrap();

                    let node_a = (*node_p.as_ptr()).left.unwrap();
                    (*node_a.as_ptr()).is_red = false;
                    let node_c = (*node_a.as_ptr()).right.unwrap();
                    (*node_c.as_ptr()).is_red = false;
                    let node_e = (*node_c.as_ptr()).left;
                    let node_d = (*node_c.as_ptr()).right;
                    (*node_c.as_ptr()).is_red = false;
                    (*node_c.as_ptr()).parent = None;
                    (*node_c.as_ptr()).left = Some(node_a);
                    (*node_a.as_ptr()).parent = Some(node_c);
                    (*node_c.as_ptr()).right = Some(node_p);
                    (*node_p.as_ptr()).parent = Some(node_c);
                    (*node_p.as_ptr()).left = node_d;
                    if let Some(n_d) = node_d {
                        (*n_d.as_ptr()).parent = Some(node_p);
                    }
                    (*node_a.as_ptr()).right = node_e;
                    if let Some(n_e) = node_e {
                        (*n_e.as_ptr()).parent = Some(node_a);
                    }
                    (*fixed_head.as_ptr()).left = Some(node_c);
                    (*fixed_head.as_ptr()).left
                }
            }
        }

        /// Rotate left without parent
        /// A is root
        ///
        /// ```text
        ///             A                  C
        ///            / \\               //\
        ///           B    C     =>      A   D
        ///               / \           / \
        ///              E   D         B   E
        ///
        /// ```
        ///
        /// Rotate left  with parent
        ///
        /// ```text
        ///             P                  P
        ///             |                  |
        ///             A                  C
        ///            / \\               //\
        ///           B    C     =>      A   D
        ///               / \           / \
        ///              E   D         B   E
        ///
        /// ```
        unsafe fn rotate_left(&mut self, node_a: NonNull<Node<T>>) -> Link<T> {
            unsafe {
                if let Some(parent) = (*node_a.as_ptr()).parent {
                    let mut node_a_from_left = false;
                    if let Some(p_node_a) = (*parent.as_ptr()).left
                        && std::ptr::eq(p_node_a.as_ptr(), node_a.as_ptr())
                    {
                        node_a_from_left = true;
                    }
                    let node_a = if node_a_from_left {
                        (*parent.as_ptr()).left.unwrap()
                    } else {
                        (*parent.as_ptr()).right.unwrap()
                    };
                    let node_c = (*node_a.as_ptr()).right.unwrap();
                    (*node_c.as_ptr()).is_red = (*node_a.as_ptr()).is_red;
                    (*node_a.as_ptr()).is_red = true;
                    (*node_c.as_ptr()).parent = Some(parent);
                    if node_c.as_ref().left.is_some() {
                        let mut node_e = (*node_c.as_ptr()).left;
                        if let Some(e) = &mut node_e {
                            (*e.as_ptr()).parent = Some(node_a);
                        }
                        (*node_a.as_ptr()).right = node_e;
                    } else {
                        (*node_a.as_ptr()).right = None;
                    }
                    (*node_c.as_ptr()).left = Some(node_a);
                    (*node_a.as_ptr()).parent = Some(node_c);
                    if node_a_from_left {
                        (*parent.as_ptr()).left = Some(node_c);
                        (*parent.as_ptr()).left
                    } else {
                        (*parent.as_ptr()).right = Some(node_c);
                        (*parent.as_ptr()).right
                    }
                } else {
                    let fixed_head = self.fixed_head.unwrap();
                    let node_a = (*fixed_head.as_ptr()).left.unwrap();
                    let node_c = (*node_a.as_ptr()).right.unwrap();
                    (*node_c.as_ptr()).is_red = (*node_a.as_ptr()).is_red;
                    (*node_a.as_ptr()).is_red = true;
                    if node_c.as_ref().left.is_some() {
                        let mut node_e = (*node_c.as_ptr()).left;
                        if let Some(e) = &mut node_e {
                            (*e.as_ptr()).parent = Some(node_a);
                        }
                        (*node_a.as_ptr()).right = node_e;
                    } else {
                        (*node_a.as_ptr()).right = None;
                    }
                    (*node_c.as_ptr()).left = Some(node_a);
                    (*node_a.as_ptr()).parent = Some(node_c);
                    (*node_c.as_ptr()).parent = None;
                    (*fixed_head.as_ptr()).left = Some(node_c);
                    (*fixed_head.as_ptr()).left
                }
            }
        }

        /// Rotate right without parent
        /// A is root
        ///
        /// ```text
        ///              A               B
        ///            // \             / \\
        ///            B   C     =>    E    A
        ///          // \                  / \
        ///         E    D                D   C
        /// ```
        ///
        /// Rotate right with parent
        ///
        /// ```text
        ///                P               P
        ///                |               |
        ///                A               B
        ///              // \             / \\
        ///              B   C     =>    E    A
        ///            // \                  / \
        ///           E    D                D   C
        ///
        /// ```
        unsafe fn rotate_right(&mut self, node_a: NonNull<Node<T>>) -> Link<T> {
            unsafe {
                if let Some(parent) = (*node_a.as_ptr()).parent {
                    let mut node_a_from_left = false;
                    if let Some(p_node_a) = (*parent.as_ptr()).left
                        && std::ptr::eq(p_node_a.as_ptr(), node_a.as_ptr())
                    {
                        node_a_from_left = true;
                    }
                    let node_a = if node_a_from_left {
                        (*parent.as_ptr()).left.unwrap()
                    } else {
                        (*parent.as_ptr()).right.unwrap()
                    };
                    let node_b = (*node_a.as_ptr()).left.unwrap();
                    (*node_b.as_ptr()).parent = Some(parent);
                    (*node_b.as_ptr()).is_red = (*node_a.as_ptr()).is_red;
                    (*node_a.as_ptr()).is_red = true;
                    if node_b.as_ref().right.is_some() {
                        let mut node_d = (*node_b.as_ptr()).right;
                        if let Some(d) = &mut node_d {
                            (*d.as_ptr()).parent = Some(node_a);
                        }
                        (*node_a.as_ptr()).left = node_d;
                    } else {
                        (*node_a.as_ptr()).left = None;
                    }
                    (*node_b.as_ptr()).right = Some(node_a);
                    (*node_a.as_ptr()).parent = Some(node_b);
                    if node_a_from_left {
                        (*parent.as_ptr()).left = Some(node_b);
                        (*parent.as_ptr()).left
                    } else {
                        (*parent.as_ptr()).right = Some(node_b);
                        (*parent.as_ptr()).right
                    }
                } else {
                    let fixed_head = self.fixed_head.unwrap();
                    let node_a = (*fixed_head.as_ptr()).left.unwrap();
                    let node_b = (*node_a.as_ptr()).left.unwrap();
                    (*node_b.as_ptr()).is_red = (*node_a.as_ptr()).is_red;
                    (*node_a.as_ptr()).is_red = true;
                    if node_b.as_ref().right.is_some() {
                        let mut node_d = (*node_b.as_ptr()).right;
                        if let Some(d) = &mut node_d {
                            (*d.as_ptr()).parent = Some(node_a);
                        }
                        (*node_a.as_ptr()).left = node_d;
                    } else {
                        (*node_a.as_ptr()).left = None;
                    }
                    (*node_b.as_ptr()).right = Some(node_a);
                    (*node_a.as_ptr()).parent = Some(node_b);
                    (*node_b.as_ptr()).parent = None;
                    (*fixed_head.as_ptr()).left = Some(node_b);
                    (*fixed_head.as_ptr()).left
                }
            }
        }

        /// Flip color
        ///
        /// ```text
        ///             |          ||
        ///             A    =>    A
        ///           // \\       / \
        ///          B    C      B   C
        ///
        /// ```
        unsafe fn flip_colors(&mut self, mut node: NonNull<Node<T>>) {
            unsafe {
                if node.as_ref().left.is_some() && node.as_ref().right.is_some() {
                    if let Some(ref mut left) = node.as_mut().left {
                        left.as_mut().is_red = false;
                    }
                    if let Some(ref mut right) = node.as_mut().right {
                        right.as_mut().is_red = false;
                    }
                    node.as_mut().is_red = true;

                    if (*node.as_ptr()).parent.is_none() {
                        node.as_mut().is_red = false;
                    }
                }
            }
        }

        unsafe fn check_put_balancing(&mut self, node: NonNull<Node<T>>) -> OperationPut {
            unsafe {
                if node.as_ref().right.is_some() {
                    let r = node.as_ref().right.unwrap();
                    if node.as_ref().left.is_some() && !node.as_ref().is_red {
                        let l = node.as_ref().left.unwrap();
                        if l.as_ref().is_red && r.as_ref().is_red {
                            return OperationPut::FlipColors;
                        }
                    }
                    if r.as_ref().is_red {
                        return OperationPut::Left;
                    }
                }
                if node.as_ref().is_red && node.as_ref().left.is_some() {
                    let l = node.as_ref().left.unwrap();
                    if l.as_ref().is_red {
                        return OperationPut::Right;
                    }
                }
                OperationPut::Nothing
            }
        }

        unsafe fn put_balancing(&mut self, next: NonNull<Node<T>>) {
            unsafe {
                let mut next = next;
                loop {
                    match self.check_put_balancing(next) {
                        OperationPut::Left => {
                            if (*next.as_ptr()).is_red {
                                if let Some(n) = self.rotate_left_right_flip_color(next) {
                                    next = n;
                                }
                            } else {
                                if let Some(n) = self.rotate_left(next) {
                                    next = n;
                                }
                            }
                        }
                        OperationPut::Right => {
                            if (*next.as_ptr()).parent.is_some() {
                                let node_a = (*next.as_ptr()).parent.unwrap();
                                if let Some(n) = self.rotate_right(node_a) {
                                    next = n;
                                }
                            }
                        }
                        OperationPut::FlipColors => {
                            self.flip_colors(next);
                            if (*next.as_ptr()).parent.is_some() {
                                next = (*next.as_ptr()).parent.unwrap();
                            } else {
                                break;
                            }
                        }
                        OperationPut::Nothing => {
                            break;
                        }
                    }
                }
            }
        }

        unsafe fn find_put_parent_candidate(&mut self, parent: Link<T>, elem: &T) -> Link<T> {
            unsafe {
                if let Some(parent) = parent {
                    match elem.cmp(&parent.as_ref().value) {
                        Ordering::Equal => None,
                        Ordering::Less => {
                            if (*parent.as_ptr()).left.is_some() {
                                self.find_put_parent_candidate((*parent.as_ptr()).left, elem)
                            } else {
                                Some(parent)
                            }
                        }
                        Ordering::Greater => {
                            if (*parent.as_ptr()).right.is_some() {
                                self.find_put_parent_candidate((*parent.as_ptr()).right, elem)
                            } else {
                                Some(parent)
                            }
                        }
                    }
                } else {
                    parent
                }
            }
        }

        unsafe fn attach_node(&mut self, parent: NonNull<Node<T>>, elem: T) -> bool {
            unsafe {
                match elem.cmp(&parent.as_ref().value) {
                    Ordering::Equal => false,
                    Ordering::Less => {
                        (*parent.as_ptr()).left = Node::new_red(elem, parent);
                        true
                    }
                    Ordering::Greater => {
                        (*parent.as_ptr()).right = Node::new_red(elem, parent);
                        true
                    }
                }
            }
        }

        /// Returns the default iterator over the tree.
        ///
        /// The default traversal is in-order (`LNR`), so values are yielded in
        /// ascending order.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([3, 1, 2]);
        ///
        /// let values: Vec<i32> = tree.iter().copied().collect();
        ///
        /// assert_eq!(values, vec![1, 2, 3]);
        /// ```
        pub fn iter(&self) -> IterInOrder<'_, T> {
            self.iter_inorder()
        }

        /// Returns an in-order (`LNR`) iterator.
        ///
        /// Values are yielded in ascending order.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([3, 1, 2]);
        ///
        /// assert_eq!(
        ///     tree.iter_inorder().copied().collect::<Vec<_>>(),
        ///     vec![1, 2, 3]
        /// );
        /// ```
        pub fn iter_inorder(&self) -> IterInOrder<'_, T> {
            unsafe { IterInOrder::new(leftmost_child_in_order(self.get_root()), self.count) }
        }

        /// Returns a reverse in-order (`RNL`) iterator.
        ///
        /// Values are yielded in descending order.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([3, 1, 2]);
        ///
        /// assert_eq!(
        ///     tree.iter_reverse_inorder().copied().collect::<Vec<_>>(),
        ///     vec![3, 2, 1]
        /// );
        /// ```
        pub fn iter_reverse_inorder(&self) -> IterReverseInOrder<'_, T> {
            unsafe {
                IterReverseInOrder::new(
                    rightmost_child_reverse_in_order(self.get_root()),
                    self.count,
                )
            }
        }

        /// Returns a pre-order (`NLR`) iterator.
        ///
        /// The current node is visited before its left and right subtrees.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([4, 2, 6, 1, 3, 5, 7]);
        ///
        /// let values: Vec<i32> = tree.iter_preorder().copied().collect();
        ///
        /// assert_eq!(values.len(), tree.len());
        /// ```
        pub fn iter_preorder(&self) -> IterPreOrder<'_, T> {
            IterPreOrder::new(self.get_root(), self.count)
        }

        /// Returns a post-order (`LRN`) iterator.
        ///
        /// The left and right subtrees are visited before the current node.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([4, 2, 6, 1, 3, 5, 7]);
        ///
        /// let values: Vec<i32> = tree.iter_postorder().copied().collect();
        ///
        /// assert_eq!(values.len(), tree.len());
        /// ```
        pub fn iter_postorder(&self) -> IterPostOrder<'_, T> {
            unsafe {
                let first = self.get_root().map(|root| leaf_post_order(root));
                IterPostOrder::new(first, self.count)
            }
        }

        /// Returns all values in level-order traversal.
        ///
        /// Nodes are visited level by level, starting from the root.
        ///
        /// # Examples
        ///
        /// ```
        /// use rbtree_extended::RedBlackTree;
        ///
        /// let mut tree = RedBlackTree::new();
        /// tree.extend([4, 2, 6, 1, 3, 5, 7]);
        ///
        /// let values = tree.iter_level_order();
        ///
        /// assert_eq!(values.len(), tree.len());
        /// ```
        pub fn iter_level_order(&self) -> Vec<&T> {
            let mut ret: Vec<&T> = vec![];
            if let Some(root) = self.get_root() {
                iter_level_order_impl(root, &mut ret);
            }
            ret
        }
    }

    impl<'a, T: Ord + Default> std::iter::IntoIterator for &'a RedBlackTree<T> {
        type IntoIter = IterInOrder<'a, T>;
        type Item = &'a T;

        fn into_iter(self) -> Self::IntoIter {
            self.iter()
        }
    }

    impl<T: Ord + Default> Drop for RedBlackTree<T> {
        fn drop(&mut self) {
            unsafe {
                if let Some(fixed_head) = self.fixed_head {
                    self.remove_tree((*fixed_head.as_ptr()).left);
                    let _ = Box::from_raw(fixed_head.as_ptr());
                }
                self.fixed_head = None;
            }
        }
    }

    fn find_node<T: Ord>(fromnode: Link<T>, value: &T) -> Link<T> {
        unsafe {
            if let Some(fromnode) = fromnode {
                match value.cmp(&(*fromnode.as_ptr()).value) {
                    Ordering::Equal => Some(fromnode),
                    Ordering::Less => find_node((*fromnode.as_ptr()).left, value),
                    Ordering::Greater => find_node((*fromnode.as_ptr()).right, value),
                }
            } else {
                fromnode
            }
        }
    }

    fn helper_display_tree<T: Display>(node: NonNull<Node<T>>) -> String {
        unsafe {
            let mut s: String = "".into();
            let color = if (*node.as_ptr()).is_red {
                "[color=\"red\"]"
            } else {
                "[color=\"black\"]"
            };

            if let Some(left) = (*node.as_ptr()).left {
                s.push_str(&format!(
                    "\t{n1}->{n2} {color1}; {n1} {color1}; {n2} {color2};\n",
                    n1 = (*node.as_ptr()).value,
                    n2 = (*left.as_ptr()).value,
                    color1 = color,
                    color2 = if (*left.as_ptr()).is_red {
                        "[color=\"red\"]"
                    } else {
                        "[color=\"black\"]"
                    },
                ));
                s.push_str(&helper_display_tree(left));
            } else if (*node.as_ptr()).right.is_some() {
                s.push_str(&format!(
                    "\t{n1}->node_null_{n1} [color=\"grey\"]; {n1} {color1};\n",
                    n1 = (*node.as_ptr()).value,
                    color1 = color
                ));
                s.push_str(&format!(
                    "\tnode_null_{n1}[label=\"null\"]\n",
                    n1 = (*node.as_ptr()).value
                ));
            }

            if let Some(right) = (*node.as_ptr()).right {
                s.push_str(&format!(
                    "\t{n1}->{n2} {color1}; {n1} {color1}; {n2} {color2};\n",
                    n1 = (*node.as_ptr()).value,
                    n2 = (*right.as_ptr()).value,
                    color2 = if (*right.as_ptr()).is_red {
                        "[color=\"red\"]"
                    } else {
                        "[color=\"black\"]"
                    },
                    color1 = color
                ));
                s.push_str(&helper_display_tree(right));
            } else {
                s.push_str(&format!(
                    "\t{n1}->node_null_{n1} [color=\"grey\"]; {n1} {color1};\n",
                    n1 = (*node.as_ptr()).value,
                    color1 = color
                ));
                s.push_str(&format!(
                    "\tnode_null_{}[label=\"null\"]\n",
                    (*node.as_ptr()).value
                ));
            }
            s
        }
    }

    impl<T: Ord + Default> Default for RedBlackTree<T> {
        fn default() -> Self {
            Self::new()
        }
    }

    impl<T: Ord + Default + Clone> Clone for RedBlackTree<T> {
        fn clone(&self) -> Self {
            let mut new_list = Self::new();
            for value in self {
                new_list.insert(value.clone());
            }
            new_list
        }
    }

    impl<T: Ord + Default> Extend<T> for RedBlackTree<T> {
        fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
            for value in iter {
                self.insert(value);
            }
        }
    }

    impl<T: Ord + Default> FromIterator<T> for RedBlackTree<T> {
        fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
            let mut list = Self::new();
            list.extend(iter);
            list
        }
    }

    impl<T: Ord + Default + Debug> Debug for RedBlackTree<T> {
        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
            f.debug_list().entries(self).finish()
        }
    }

    impl<T: Ord + Default> PartialEq for RedBlackTree<T> {
        fn eq(&self, other: &Self) -> bool {
            self.len() == other.len() && self.iter_inorder().eq(other.iter_inorder())
        }
    }

    impl<T: Ord + Default> Eq for RedBlackTree<T> {}

    impl<T: Ord + Default> PartialOrd for RedBlackTree<T> {
        fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
            Some(self.cmp(other))
        }
    }

    impl<T: Ord + Default> Ord for RedBlackTree<T> {
        fn cmp(&self, other: &Self) -> Ordering {
            self.iter_inorder().cmp(other.iter_inorder())
        }
    }

    impl<T: Ord + Default + std::hash::Hash> std::hash::Hash for RedBlackTree<T> {
        fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
            self.len().hash(state);
            for item in self {
                item.hash(state);
            }
        }
    }
}

Здесь не нужно искать все элементы и сравнивать их вручную.

Мы сразу получаем ближайших соседей в отсортированном порядке.


B-Tree

Визуализация работы B-Tree

В отличии от бинарных деревьев (BST), где у узла максимум 2 ребёнка, сбалансированное B-Tree оптимизировано под многоуровневую модель памяти дерева.

             [ 20 | 40 | 60 ]
              /    |    |    \
             /     |    |     \
        ключи<20  20-40 40-60  ключи>60
B-Tree ознакомление

Каждый узел может содержать несколько ключей и иметь несколько дочерних узлов. Количество ключей и потомков ограничено параметрами B-Tree. Благодаря этому дерево обычно имеет значительно меньшую высоту, чем бинарные деревья поиска. Поиск требует меньше переходов по ссылкам между узлами, что может повысить производительность за счёт лучшей локальности данных и меньшего количества промахов кэша. Однако итоговая скорость зависит от реализации и от того, сколько сравнений требуется внутри каждого узла.

Узел хранит несколько отсортированных ключей. Если в нём k ключей, у внутреннего узла обычно k + 1 дочерних узлов. Ключи разделяют диапазоны значений для поиска.

B-Tree уменьшает количество уровней дерева и обращений к узлам, что особенно полезно при работе с дисками, страницами памяти и большими массивами данных. Например, B-Tree и его разновидность B+ Tree широко используются в индексах баз данных и файловых системах. При этом B-Tree также может быть эффективным в оперативной памяти.

Главная идея:

  • оптимизирован под работу блоками
  • много ключей в одном узле
  • мало уровней дерева

"меньше уровней дерева -> меньше переходов по указателям -> меньше обращений к медленной памяти"

B-Tree особенно часто используют в базах данных и файловых системах:

  • при работе с дисками
  • SSD
  • страничной памяти
  • индексами баз данных (PostgreSQL/MySQL/SQLite indexes)
  • key-value databases
  • filesystem metadata
  • storage engines

Сильные стороны

  • Намного меньше последовательных переходов по указателям в памяти, чем у бинарных деревьев. B-Tree хранит много ключей в одном узле, что позволяет эффективнее использовать CPU cache и уменьшить число переходов между узлами
  • Очень маленькая высота дерева
  • Один узел хранит много ключей
  • Хорошо использует дисковые страницы и cache lines, так как все ключи узла рядом
  • Поиск, вставка и удаление —
  • Отлично подходит для огромных наборов данных
  • Хорошо работает с range queries
  • Все листья находятся на одной глубине

Слабые стороны

  • Для маленьких структур в RAM часто избыточно
  • Один узел занимает больше памяти

Сложность операций

ОперацияB-Tree
SearchO(log n)
InsertO(log n)
RemoveO(log n)
Min / MaxO(log n)
RangeO(log n + k)
TraversalO(n)

Память

B-Tree часто эффективнее по памяти, чем бинарные деревья, благодаря меньшим накладным расходам на узел и указатели, потому что каждый узел B-Tree хранит несколько ключей и указателей на дочерние узлы, тогда как в бинарном дереве каждый ключ обычно занимает отдельный узел с двумя указателями.

Когда использовать

B-Tree особенно хорош, если данные:

  • очень большие
  • не помещаются целиком в CPU cache
  • лежат на диске или SSD
  • хранятся страницами
  • часто читаются диапазонами
  • нужны отсортированные ключи
  • постоянно вставляются и удаляются

Типичные применения: database indexes filesystem indexes storage engines large ordered maps on-disk key-value stores

Когда не использовать

  • данных мало, для небольшого контейнера 100–1000 элементов в памяти Red-Black Tree часто проще и достаточно хорош.
  • всё помещается в RAM
  • нужна максимально простая структура
  • порядок не нужен
  • структура маленькая и локальная
  • нужен только min/max — тогда heap проще

Основные понятия

Node

В B-Tree узел хранит несколько ключей: [20 | 40 | 60]

Order / Degree

Order или Degree определяет ограничения на количество ключей в одном узле.

  • Order m — часто означает максимальное количество дочерних узлов: до m детей и m − 1 ключей в узле.
  • Minimum degree t — в классическом определении B-Tree задаёт минимум t − 1 и максимум 2t − 1 ключей в узле, кроме корня.

На практике размер узла часто выбирают с учётом размера ключей, указателей и целевого размера блока памяти.

Чем больше degree, тем больше ключей на узел и меньше высота дерева.

Но слишком большой узел тоже не всегда выгоден.

Если дерево оптимизируют для работы с диском, размер узла стараются приблизить к размеру страницы или блока ввода-вывода. Если дерево работает в оперативной памяти, учитывают кэш процессора, размер ключей и значений, количество указателей и стоимость поиска внутри узла.

Например, в узле на 4 КиБ можно разместить гораздо больше ключей, чем в узле на 64 байта, если размеры ключей и указателей одинаковы.

Split

Если узел переполнен то он разделяется на два узла,а средний ключ поднимается к родителю.

Merge

При удалении может оказаться, что в узле слишком мало ключей. Тогда он может объединиться с соседним узлом в один более крупный узел.

B-Tree vs Red-Black Tree

important

B-Tree может предоставлять тот же функционал, что и Red-Black Tree, и при этом обеспечивать более высокую производительность поиска.

У B-Tree и Red-Black Tree основные операции практически одинаковые с точки зрения интерфейса:

  • Search — поиск ключа.
  • Insert — вставка ключа.
  • Delete — удаление ключа.
  • Min / Max — поиск минимального и максимального ключа.
  • Predecessor / Successor — поиск предыдущего и следующего ключа по порядку.
  • Range Query — получение ключей в заданном диапазоне.
  • Traversal / Iteration — обход ключей в отсортированном порядке.

Отличие во внутренней реализации. Red-Black Tree балансируется с помощью цветов узлов и поворотов, а B-Tree — с помощью разделения и объединения узлов, содержащих несколько ключей.

Важный момент, в стандартной библиотеке Rust нет коллекции на основе Red-Black Tree, но есть две коллекции на основе B-Tree:

Например, выбираем обытия по диапазону:

use std::collections::BTreeMap;

#[derive(Debug)]
struct Event {
    id: u32,
    name: String,
}
fn main() {
    let mut events = BTreeMap::new();
    events.insert(
        1_700_000_000,
        Event {
            id: 1,
            name: "Login".into(),
        },
    );
    events.insert(
        1_700_000_100,
        Event {
            id: 2,
            name: "Payment".into(),
        },
    );
    events.insert(
        1_700_000_200,
        Event {
            id: 3,
            name: "Logout".into(),
        },
    );
    events.insert(
        1_700_000_300,
        Event {
            id: 4,
            name: "Login".into(),
        },
    );

    let from = 1_700_000_050;
    let to = 1_700_000_250;

    println!("События в диапазоне timestamp:");

    for (timestamp, event) in events.range(from..=to) {
        println!(
            "{} -> id={} name={}",
            timestamp,
            event.id,
            event.name
        );
    }
}

Heap (Priority Queue)

Визуализация работы Heap

Визуализация работы Min-Heap

Heap (куча) — это специализированное дерево, которое оптимизировано не для поиска произвольного элемента, а для быстрого доступа к минимальному или максимальному элементу. Основная задача Heap — быстро получать элемент с наибольшим или наименьшим приоритетом, в зависимости от типа кучи. Для пользователя Heap важен не как “дерево”, а как структура с очень узкой гарантией.

А его древовидная форма — это уже внутренний механизм, который позволяет после изменения дерева быстро восстановить его свойство, заменимв корень.

Поэтому Heap особенно полезен, когда постоянно меняется набор кандидатов, но каждый раз нужен только самый приоритетный из них.

Heap ознакомление

Есть два основных варианта:

  • Max-Heap → Самый большой элемент всегда в корне. Каждый родитель должен быть больше или равен своим детям, поэтому максимальный элемент всегда оказывается в корне.
  • Min-Heap → Самый маленький элемент всегда в корне.

Память

Binary Heap обычно хранится не через Node и указатели, а прямо в массиве.

Связи между узлами вычисляются по индексам.

Для элемента с индексом i:

  • left = 2*i + 1
  • right = 2*i + 2
  • parent = (i - 1) / 2

Когда использовать

Heap особенно хорош, если главная задача - постоянно получать самый важный/приоритетный элемент:

  • максимальный priority
  • минимальное время
  • минимальная стоимость
  • самая короткая дистанция

Типичные применения:

  • Priority Queue
  • Task Scheduler
  • таймеры
  • Dijkstra и A* (используют самую перспективную вершину на каждом шаге)
  • Huffman coding
  • Top-K элементов
  • merge нескольких отсортированных потоков
  • алгоритм Прима
  • Heap Sort

Основные понятия

Max-Heap поддерживает максимальный элемент в root с помощью двух операций:

  • Просеивание вверх (sift-up) при вставке. Новый элемент добавляется в конец массива, то есть в следующую свободную позицию полного бинарного дерева. Затем он сравнивается с родителем. Если родитель меньше, они меняются местами. Процесс повторяется, пока свойство кучи не будет восстановлено или элемент не достигнет корня. На каждом шаге элемент сравнивается только со своим родителем.
  • Просеивание вниз (sift-down) при удалении корня. Корень заменяется последним элементом массива, после чего этот элемент сравнивается с детьми. Если один из детей больше, элемент меняется местами с бо́льшим ребёнком. Процесс повторяется вниз, пока свойство кучи не будет восстановлено.

Complete Binary Tree. Binary Heap должен быть полным бинарным деревом. Т.е. уровни заполняются: сверху вниз слева направо. Именно complete structure позволяет хранить дерево в Vec.

Heapify - преобразование обычного массива в корректный Heap.


Упражнения

В Rust есть готовая реализация std::collections::BinaryHeap — это Max-Heap по умолчанию.

1. Task Scheduler. Выполнять задачу с максимальным priority:

use std::cmp::Ordering;
use std::collections::BinaryHeap;

#[derive(Debug)]
struct Task {
    id: u32,
    priority: u32,
    name: String,
}
impl PartialEq for Task {
    fn eq(&self, other: &Self) -> bool {
        self.priority == other.priority && self.id == other.id
    }
}
impl Eq for Task {}
impl PartialOrd for Task {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}
impl Ord for Task {
    fn cmp(&self, other: &Self) -> Ordering {
        self.priority
            .cmp(&other.priority)
            .then_with(|| self.id.cmp(&other.id))
    }
}
fn main() {
    let mut scheduler = BinaryHeap::new();

    // Добавляем задачи в произвольном порядке.
    scheduler.push(Task {
        id: 1,
        priority: 10,
        name: "Send email".into(),
    });
    scheduler.push(Task {
        id: 2,
        priority: 100,
        name: "Fix production".into(),
    });
    scheduler.push(Task {
        id: 3,
        priority: 50,
        name: "Generate report".into(),
    });
    scheduler.push(Task {
        id: 4,
        priority: 80,
        name: "Deploy release".into(),
    });

    println!("Следующая задача:");
    if let Some(task) = scheduler.peek() {
        println!(
            "priority={} task={}",
            task.priority,
            task.name
        );
    }

    println!("\nВыполняем задачи:");
    while let Some(task) = scheduler.pop() {
        println!(
            "priority={} id={} task={}",
            task.priority,
            task.id,
            task.name
        );
    }
}

2. Timer Queue

Хранить время запуска задач:

10:01
10:05
10:20

Min-Heap всегда показывает ближайший таймер.

В Rust BinaryHeap по умолчанию — Max-Heap, поэтому для Timer Queue удобно использовать Reverse, чтобы получить Min-Heap.

use std::cmp::Reverse;
use std::collections::BinaryHeap;

fn main() {
    let mut timers = BinaryHeap::new();

    // Храним время запуска в формате HHMM.
    timers.push(Reverse(1020));
    timers.push(Reverse(1001));
    timers.push(Reverse(1005));

    println!("Ближайший таймер:");
    if let Some(Reverse(time)) = timers.peek() {
        println!("{time}");
    }

    println!("\nОбрабатываем таймеры по времени:");
    while let Some(Reverse(time)) = timers.pop() {
        println!("{time}");
    }
}

3. Top-K

Top-K — это задача найти K наибольших или наименьших элементов из набора данных. Для этой задачи часто используют Heap, потому что он позволяет эффективно поддерживать нужное количество лучших элементов.

Например найти: 5 самых популярных товаров, не сортируя весь массив.

use std::cmp::Reverse;
use std::collections::BinaryHeap;

fn main() {
    let products = vec![
        ("Laptop", 1200),
        ("Phone", 2500),
        ("Headphones", 900),
        ("Keyboard", 700),
        ("Mouse", 1100),
        ("Monitor", 1800),
        ("Tablet", 1300),
        ("Camera", 600),
        ("Speaker", 950),
        ("Watch", 1600),
        ("Printer", 300),
        ("Router", 500),
        ("Microphone", 1400),
        ("Webcam", 800),
        ("SSD", 2100),
    ];

    const K: usize = 5;

    // Min-Heap:
    // в корне находится самый слабый товар среди текущего Top-5
    let mut top = BinaryHeap::new();

    // Формируем Top-5
    for (name, views) in products {
        top.push(Reverse((views, name)));

        // Если элементов стало больше 5, удаляем самый слабый товар.
        if top.len() > K {
            top.pop();
        }
    }

    println!("5 самых популярных товаров:");
    // Смотрим Top-5, не удаляя элементы из heap.
    // Для Reverse into_sorted_vec() уже даёт товары от самого популярного к менее популярному.
    let result = top.clone().into_sorted_vec();

    for Reverse((views, name)) in result {
        println!("{name}: {views}");
    }
    println!("\nПришёл новый товар: VR Headset — 1700");

    // Добавляем новый товар
    top.push(Reverse((1700, "VR Headset")));

    // Heap временно стал размером 6
    // Удаляем самый слабый товар из Top-5
    if top.len() > K {
        if let Some(Reverse((views, name))) = top.pop() {
            println!("Из Top-5 выбыл: {name}: {views}");
        }
    }

    println!("\nОбновлённый Top-5:");
    // Снова смотрим очередь, не разрушая её
    let result = top.clone().into_sorted_vec();
    for Reverse((views, name)) in result {
        println!("{name}: {views}");
    }
}

4. Merge sorted streams

Есть несколько уже отсортированных потоков:

A: 1 5 9
B: 2 6 10
C: 3 4 11

Нужно получить один общий отсортированный поток. Min-Heap помогает постоянно выбирать минимальный следующий элемент.

Мы знаем: внутри каждого потока меньший элемент всегда стоит раньше большего. Значит, чтобы найти самый маленький элемент вообще среди всех потоков, нам не надо смотреть на все элементы. Достаточно посмотреть только на первый ещё не использованный элемент каждого потока. Т.е. в heap никогда не лежат все данные, для трёх потоков там максимум 3 элемента

use std::cmp::Reverse;
use std::collections::BinaryHeap;

fn main() {
    let streams = [
        vec![1, 5, 9],
        vec![2, 6, 10],
        vec![3, 4, 11],
    ];

    // В heap храним:
    // (значение, номер потока, индекс элемента внутри потока)
    let mut heap = BinaryHeap::new();

    // Добавляем первый элемент каждого потока.
    for (stream_index, stream) in streams.iter().enumerate() {
        if let Some(&value) = stream.first() {
            heap.push(Reverse((value, stream_index, 0)));
        }
    }

    let mut result = Vec::new();

    while let Some(Reverse((value, stream_index, value_index))) = heap.pop() {
        // Это минимальный элемент среди текущих голов всех потоков
        result.push(value);

        let next_index = value_index + 1;

        // Добавляем следующий элемент из того же потока
        if let Some(&next_value) = streams[stream_index].get(next_index) {
            heap.push(Reverse((
                next_value,
                stream_index,
                next_index,
            )));
        }
    }

    println!("{result:?}");
}

Graph

Graph — это структура данных для описания объектов и произвольных связей между ними. Объекты называются вершинами (vertices), а связи между ними — рёбрами (edges). У графа могут быть циклы, произвольные связи и отсутствовать иерархия.

Здесь нет обязательного корня, родителя или ребёнка.

Связи могут быть любыми:

A----B
| \  |
|  \ |
C----D

Главное преимущество Graph: он хранит не порядок элементов, а отношения между ними

Graph ознакомление

Сильные стороны

  • Гибкие связи. Вершина может быть связана с любым количеством других вершин.
  • Сложные отношения. Можно моделировать циклы, сети, взаимные и направленные связи.
  • Разные виды рёбер. Рёбра могут иметь вес, направление или дополнительные данные — например, стоимость поездки или время передачи данных.
  • Подходит для анализа связей. Можно искать пути, кратчайшие маршруты, связанные компоненты и достижимость вершин.

Слабые стороны

  • Нет быстрого универсального поиска пути. Чтобы найти путь между двумя вершинами, может потребоваться обойти значительную часть графа.
  • Расход памяти зависит от представления. Матрица смежности требует памяти, даже если связей мало. Список смежности обычно требует , где число вершин, а — число рёбер.
  • Алгоритмы могут быть сложными. Поиск кратчайшего пути, обнаружение циклов и анализ связности требуют отдельных алгоритмов.
  • Нет автоматической сортировки. В отличие от BST и B-Tree, граф сам по себе не поддерживает упорядоченный поиск по ключам.

Память

Граф можно хранить по-разному, и от этого очень сильно зависит расход памяти.

Список смежности (Adjacency List). Храним только реальные связи. Для каждой вершины храним список её соседей в Vec<Vec<usize>> если вершины имеют числовые индексы от 0 до V - 1, часто удобнее и экономнее использовать иначе можно организовать граф через HashMap<Node, Vec<Node>> или если нужна более высокая производительность для поиска конкретного ребра, можно использовать HashSet вместо Vec - HashMap<Node, HashSet<Node>>.

Например граф:

A---B
|   | \
C---D--E

Нам нужно хранить сами вершины плюс все связи.

Можно хранить так:

A -> B, C
B -> A, D, E
C -> A, D
D -> B, C, E
E -> B, D

Память складывается из это количество вершин и это количество рёбер.

Поэтому список смежности применяется чаще и используется в Sparse graph (разреженный граф) — граф, в котором относительно мало рёбер по сравнению с максимально возможным количеством.

Sparse graph

Если граф хранится в виде списка смежности (Adjacency List) и количество рёбер (E) примерно равно количеству вершин (V), то граф обычно является разреженным (Sparse Graph), и список смежности позволяет экономить память.

Сложность поиска связи между двумя вершинами составляет , где — количество соседей проверяемой вершины. Если число соседей ограничено константой, поиск выполняется за . Если же у вершины много соседей, поиск может занимать в худшем случае, что медленнее проверки в матрице смежности (Adjacency Matrix), где она выполняется за .

Поэтому для разреженных графов обычно предпочтительнее список смежности, а для плотных графов, где важна быстрая проверка наличия ребра, может быть предпочтительнее матрица смежности.

Матрицы смежности (Adjacency Matrix). Резервируем место под все возможные связи в двумерном массиве Vec<Vec<bool/u8>>.

Создаём таблицу V × V

    A B C D

A   0 1 1 0
B   1 0 0 1
C   1 0 0 1
D   0 1 1 0

где:

  • 1 означает - ребро есть
  • 0 означает - ребра нет

Память потому что для каждой пары вершин нужно отдельное место. Т.е. матрица сильно расточительна по памяти в сравнении со списком смежности, так выделяет место для связи какждый с каждым. Если для 4 вершин у списка смежности будет выделенно 4 ячейки то у матрицы ячеек

Но Adjacency Matrix нужна, когда важнее не память, а очень быстрый ответ на вопрос - Есть ли ребро между A и B? (edge(A, B)). Так как в матрице смежности мы сразу смотрим одну конкретную ячейку matrix[A][B]

Поэтому матрица смежности применяется реже и используется в Dense graph (плотный граф) — граф, в котором относительно много рёбер, то есть большинство возможных связей между вершинами существуют.

Dense graph

Сложность операций

Сложность операций Graph зависит от способа хранения графа: списка смежности (Adjacency List) и матрицы смежности (Adjacency Matrix).

Обозначения: (V) — количество вершин, (E) — количество рёбер.

ОперацияAdjacency List (список смежности)Adjacency Matrix (матрица смежности)
Добавить вершину**
Добавить ребро*
Удалить ребро
Проверить наличие ребра
Получить соседей вершины
Удалить вершину
Обход BFS / DFS
Найти кратчайший путь (Дейкстра)**

— количество рёбер, связанных с вершиной (v).

* Добавление вершины в список смежности — амортизированно, если вершины хранятся в динамическом массиве и идентификаторы позволяют добавлять их без поиска. Для матрицы добавление вершины требует расширения матрицы, поэтому указана типичная стоимость перераспределения.

** Для реализации Дейкстры с бинарной кучей и списком смежности.

Главное различие: список смежности экономнее по памяти для разреженных графов — . Матрица смежности занимает , но проверяет наличие ребра за .

Основные понятия

  • Vertex - вершина графа
  • Edge - связь между двумя вершинами
  • Degree - количество рёбер вершины. В направленном графе различают входящие in-degree и исходящие out-degree ребра
  • Directed Graph - ребро имеет направление
  • Undirected Graph - связь двусторонняя
  • Weighted Graph - у ребра есть стоимость связи
  • Unweighted Graph - все связи считаются одинаковыми
  • Path - последовательность связанных вершин A → B → D → E
  • Cycle - путь возвращается в исходную вершину
  • Connected Graph - из любой вершины можно добраться до любой другой
  • Disconnected Graph - есть отдельные компоненты без связи между собой
  • Sparse Graph - рёбер мало относительно количества возможных связей: ()
  • Dense Graph - связей очень много: ()

Когда использовать

Graph нужен, когда данные естественно описываются как: объекты + связи между объектами

город = vertex
дорога = edge

пользователь = vertex
дружба = edge

Типичные применения:

  • Карты и навигация. Вершины — перекрёстки или города, рёбра — дороги, вес рёбер — расстояние или время в пути. Алгоритмы Дейкстры и A* помогают искать маршруты.
  • Социальные сети. Вершины — пользователи, рёбра — дружба, подписки или другие отношения. Граф помогает находить общих знакомых и анализировать сообщества.
  • Компьютерные сети. Вершины — маршрутизаторы или устройства, рёбра — сетевые соединения. Граф позволяет анализировать маршруты передачи данных и точки отказа.
  • Базы знаний и рекомендации. Вершины — люди, товары, фильмы или понятия, рёбра — отношения между ними. Граф помогает находить связанные объекты и рекомендовать контент.

Упражнения

В стандартной библиотеке Rust нет готовой универсальной структуры Graph. Обычно граф реализуют самостоятельно с помощью Vec, HashMap или матрицы смежности — в зависимости от задачи. Но есть реализация графа в crate petgraph и его расширение в crate rustworkx-core

BFS и Dijkstra решают похожие задачи, но критерии разные:

  • BFS ищет путь с минимальным количеством рёбер. Он подходит для невзвешенного графа или когда каждое ребро имеет одинаковую стоимость.
  • Dijkstra ищет путь с минимальной суммой весов. Меняя передаваемую функцию cost, мы можем искать минимальное расстояние, цену или время. Все веса должны быть неотрицательными.

1. Поиск маршрута между городами Murcia и Zaragoza — по четырём критериям:

  1. Minimum number of roads — маршрут с минимальным количеством дорог (рёбер).
  2. Minimum distance — маршрут с минимальной общей дистанцией в километрах.
  3. Minimum price — маршрут с минимальной суммарной стоимостью в евро.
  4. Minimum travel time — маршрут с минимальным общим временем в минутах.

map

[dependencies]
petgraph = "0.8.3"
extern crate petgraph;
use petgraph::algo::{astar, is_cyclic_undirected};
use petgraph::graph::{NodeIndex, UnGraph};

#[derive(Clone, Copy)]
struct Road {
    distance_km: u32,
    price_eur: u32,
    minutes: u32,
}

type RoadGraph = UnGraph<&'static str, Road>;

fn print_path(graph: &RoadGraph, path: &[NodeIndex]) {
    for (i, node) in path.iter().enumerate() {
        if i > 0 {
            print!(" -> ");
        }
        print!("{}", graph[*node]);
    }
    println!();
}
fn main() {
    let mut graph = RoadGraph::new_undirected();
    let madrid = graph.add_node("Madrid");
    let murcia = graph.add_node("Murcia");
    let valencia = graph.add_node("Valencia");
    let zaragoza = graph.add_node("Zaragoza");
    graph.add_edge(madrid, murcia, Road {
        distance_km: 400,
        price_eur: 25,
        minutes: 245,
    });
    graph.add_edge(madrid, valencia, Road {
        distance_km: 360,
        price_eur: 20,
        minutes: 220,
    });
    graph.add_edge(murcia, valencia, Road {
        distance_km: 230,
        price_eur: 15,
        minutes: 145,
    });
    
    graph.add_edge(valencia, zaragoza, Road {
        distance_km: 310,
        price_eur: 18,
        minutes: 190,
    });
    graph.add_edge(madrid, zaragoza, Road {
        distance_km: 320,
        price_eur: 22,
        minutes: 200,
    });

    // 1. Minimum number of roads.
    // Each edge has weight 1.
    println!("1. Минимальное количество дорог/городов:");
    let (cost, path) = astar(
        &graph,
        murcia,
        |node| node == zaragoza,
        |_| 1u32,
        |_| 0u32,
    )
    .unwrap();

    print_path(&graph, &path);
    println!("Roads: {cost}");

    // 2. Minimum distance.
    println!("\n2. Минимальная дистанция:");
    let (distance, path) = astar(
        &graph,
        murcia,
        |node| node == zaragoza,
        |edge| edge.weight().distance_km,
        |_| 0u32,
    )
    .unwrap();

    print_path(&graph, &path);
    println!("Distance: {distance} km");

    // 3. Minimum price.
    println!("\n3. Минимальная цена маршрута:");
    let (price, path) = astar(
        &graph,
        murcia,
        |node| node == zaragoza,
        |edge| edge.weight().price_eur,
        |_| 0u32,
    )
    .unwrap();

    print_path(&graph, &path);
    println!("Price: {price} EUR");

    // 4. Minimum travel time.
    println!("\n4. Минимальное время:");
    let (minutes, path) = astar(
        &graph,
        murcia,
        |node| node == zaragoza,
        |edge| edge.weight().minutes,
        |_| 0u32,
    )
    .unwrap();

    print_path(&graph, &path);
    println!("Time: {minutes} minutes");

    // 5. Cycle detection.
    println!("\n5. Cycle detection:");
    println!(
        "Contains cycle: {}",
        is_cyclic_undirected(&graph)
    );
}

2. Социальная сеть

Для примера социальной сети на petgraph используем неориентированный граф: вершины — пользователи, рёбра — дружеские связи.

Решим три задачи: найти общих друзей двух пользователей, определить степень связи и найти компоненты связности.

  • Common friends — пользователи, которые дружат одновременно с обоими выбранными пользователями.
  • Degree of separation — минимальное количество дружеских связей между двумя пользователями. Например, 2 означает, что они связаны через одного промежуточного пользователя.
  • Connected components — группы пользователей, внутри которых все связаны друг с другом напрямую или через других пользователей. Между разными группами путей нет.

NetworkDiagram

extern crate petgraph;
use petgraph::algo::{astar, connected_components};
use petgraph::graph::{NodeIndex, UnGraph};
use petgraph::visit::EdgeRef;

type SocialGraph = UnGraph<&'static str, ()>;

fn print_path(graph: &SocialGraph, path: &[NodeIndex]) {
    for (i, user) in path.iter().enumerate() {
        if i > 0 {
            print!(" -> ");
        }
        print!("{}", graph[*user]);
    }
    println!();
}
fn main() {
    let mut graph = SocialGraph::new_undirected();

    let alice = graph.add_node("Alice");
    let bob = graph.add_node("Bob");
    let charlie = graph.add_node("Charlie");
    let diana = graph.add_node("Diana");
    let eve = graph.add_node("Eve");
    let frank = graph.add_node("Frank");
    let grace = graph.add_node("Grace");

    // Установить связи
    graph.add_edge(alice, bob, ());
    graph.add_edge(alice, charlie, ());
    graph.add_edge(bob, charlie, ());
    graph.add_edge(bob, diana, ());
    graph.add_edge(charlie, diana, ());
    graph.add_edge(diana, eve, ());

    // Отдельная группа пользователей
    graph.add_edge(frank, grace, ());

    // 1. Общие друзья
    println!("1. Общие друзья Алисы и Боба:");
    let alice_friends: Vec<NodeIndex> = graph.neighbors(alice).collect();
    let bob_friends: Vec<NodeIndex> = graph.neighbors(bob).collect();

    for user in alice_friends {
        if bob_friends.contains(&user) {
            println!("{}", graph[user]);
        }
    }
    // 2. Степень связи:
    // * 0 — пользователь связан сам с собой
    // * 1 — пользователи дружат напрямую
    // * 2 — между ними один промежуточный пользователь
    // * 3 — между ними два промежуточных пользователя
    println!("\n2. Кратчайшая цепочка дружеских связей между: Alice -> Eve");
    if let Some((distance, path)) = astar(
        &graph,
        alice,
        |user| user == eve,
        |_| 1u32,
        |_| 0u32,
    ) {
        print_path(&graph, &path);
        println!("Дистанция связи: {distance}");
    } else {
        println!("Нет связи");
    }
    // 3. Компоненты связности
    println!("\n3. Компоненты связности:");
    println!(
        "Количество компонентов: {}",
        connected_components(&graph)
    );
}

3. Dependency graph

Нужно определить порядок сборки.

package A зависит от B
package B зависит от C

Граф зависимостей: A → B → C поэтому собирать нужно в обратном порядке зависимостей: C → B → A

Это значит A нельзя собрать, пока не собран B. И B нельзя собрать, пока не собран C.

Для этого используется Topological Sort — он строит такой порядок вершин, чтобы каждая зависимость была обработана раньше того, кто от неё зависит.

Более интересный пример зависимостей:

A зависит от B
B зависит от C
D зависит от B
E зависит от C

Граф зависимостей:

A → B → C
D → B
E → C
extern crate petgraph;
use petgraph::algo::toposort;
use petgraph::graph::DiGraph;

fn main() {
    let mut graph = DiGraph::<&str, ()>::new();

    let a = graph.add_node("A");
    let b = graph.add_node("B");
    let c = graph.add_node("C");
    let d = graph.add_node("D");
    let e = graph.add_node("E");

    graph.add_edge(b, a, ());
    graph.add_edge(c, b, ());
    graph.add_edge(b, d, ());
    graph.add_edge(c, e, ());

    let order = toposort(&graph, None).unwrap();

    println!("Порядок сборки:");
    for node in order {
        println!("{}", graph[node]);
    }
}

Trie

Trie — это не бинарное дерево для хранения строк по символам, чтобы быстро искать слова по префиксу.

Главная идея: общие префиксы хранятся один раз и используются всеми задействованными узлами.

Trie работает не с целым ключом сразу, а проходит его посимвольно.

Trie особенно полезен, когда ключ — это последовательность, и решение можно принимать постепенно, проходя её часть за частью.

Trie ознакомление

Например для хранения слов: car, card, care, cat, dog

Trie будет выглядеть примерно так:

        root
       /    \
      c      d
      |      |
      a      o
     / \     |
    r   t    g
   / \
  d   e

И такие слова как car, card, care, будут использовать общие узлы и путь: c → a → r

Hash Table обычно удобнее, когда нужно проверить наличие конкретного слова. Trie особенно удобен, когда нужно находить слова по началу строки и получать все совпадения по префиксу.

Сильные стороны

  • Очень быстрый поиск слова по префиксу. Быстрее обычных Map/Set для prefix-задач
  • Удобно получать ключи в лексикографическом порядке. Если дети узлов хранятся упорядоченно, можно обходить Trie сразу в алфавитном порядке.

Слабые стороны

  • Может потреблять много памяти. У каждого узла нужно хранить ссылки на дочерние узлы, а таких узлов может быть очень много.
  • Плохо подходит для длинных ключей с малым количеством общих префиксов. Тогда Trie разрастается почти на каждый символ каждого ключа и теряет главное преимущество по памяти.

Сложность операций

ОперацияСложность
InsertO(L)
SearchO(L)
Prefix searchO(L)
DeleteO(L)

где L = длина слова

Например поиск computer, требует пройти символы: c → o → m → p → u → t → e → r т.е. 8 шагов, а количество остальных слов в Trie почти не влияет.

Время поиска зависит в основном от длины слова, а не от количества слов.

Память

Каждая вершина хранит: символ + ссылки на следующие символы + признак конца слова

У каждой вершины обычно есть структура для детей: HashMap<char, Node> или [Option<Node>; 26]

Именно поэтому Trie может быть довольно тяжёлым по памяти. Особенно много памяти расходуется, если общих префиксов мало. Тогда Trie почти не переиспользует узлы и создаёт отдельные узлы почти для каждого символа.

Когда использовать

Когда нужны операции по префиксу:

  • Автодополнение (autocomplete). Пользователь ввёл ca — быстро находим car, cat, care
  • Поиск слов по префиксу (по началу слов). Найти все слова, начинающиеся с pre, например prefix, prepare, prevent
  • Проверка существования слова. Например, есть ли в словаре слово care
  • Поиск по словарю и исправление опечаток. Trie можно использовать как часть алгоритмов проверки правописания
  • Маршрутизация по префиксам (routing prefixes, поиск URL). Например, поиск наиболее подходящего IP-маршрута по префиксу сети

Когда не использовать

Если нужен только точный поиск (лучше HashSet<String>) или поиск по ключу без поиска по префиксу (лучше HashMap)

Основные понятия

Prefix - начало слова

End of word - у каждого узла есть специальный флаг, например is_end, который показывает, заканчивается ли на этом узле какое-либо слово. В обычном Trie у каждого узла есть ровно один путь от корня. Поэтому флаг is_end однозначно определяет, заканчивается ли слово на этом пути.

Упражнения

В стандартной библиотеке Rust готового Trie нет. Поэтому есть два варианта: взять сторонний crate или реализовать Trie самостоятельно.

1. Autocomplete

use std::collections::HashMap;

#[derive(Default)]
struct TrieNode {
    children: HashMap<char, TrieNode>,
    is_end: bool,
}

#[derive(Default)]
struct Trie {
    root: TrieNode,
    len: usize,
}
impl Trie {
    fn insert(&mut self, word: &str) -> bool {
        let mut node = &mut self.root;
        for ch in word.chars() {
            node = node.children.entry(ch).or_default();
        }
        if node.is_end {
            return false;
        }
        node.is_end = true;
        self.len += 1;
        true
    }
    fn contains(&self, word: &str) -> bool {
        let mut node = &self.root;
        for ch in word.chars() {
            match node.children.get(&ch) {
                Some(child) => node = child,
                None => return false,
            }
        }
        node.is_end
    }
    fn remove(&mut self, word: &str) -> bool {
        if !self.contains(word) {
            return false;
        }
        Self::remove_from(&mut self.root, &mut word.chars());
        self.len -= 1;
        true
    }
    fn remove_from(
        node: &mut TrieNode,
        chars: &mut std::str::Chars<'_>,
    ) -> bool {
        let Some(ch) = chars.next() else {
            node.is_end = false;
            return node.children.is_empty();
        };
        let remove_child = {
            let child = node.children.get_mut(&ch).unwrap();
            Self::remove_from(child, chars)
        };
        if remove_child {
            node.children.remove(&ch);
        }
        !node.is_end && node.children.is_empty()
    }
    fn autocomplete(&self, prefix: &str) -> Vec<String> {
        let mut node = &self.root;

        for ch in prefix.chars() {
            match node.children.get(&ch) {
                Some(child) => node = child,
                None => return Vec::new(),
            }
        }
        let mut results = Vec::new();
        let mut word = prefix.to_string();

        Self::collect_words(node, &mut word, &mut results);
        results.sort();

        results
    }
    fn collect_words(
        node: &TrieNode,
        word: &mut String,
        results: &mut Vec<String>,
    ) {
        if node.is_end {
            results.push(word.clone());
        }
        for (&ch, child) in &node.children {
            word.push(ch);
            Self::collect_words(child, word, results);
            word.pop();
        }
    }
    fn len(&self) -> usize {
        self.len
    }
    #[allow(dead_code)]
    fn is_empty(&self) -> bool {
        self.len == 0
    }
}
fn main() {
    let mut trie = Trie::default();
    trie.insert("Alice");
    trie.insert("Alex");
    trie.insert("Alexander");
    trie.insert("Bob");
    trie.insert("Charlie");
    println!("Autocomplete 'Al':");
    for name in trie.autocomplete("Al") {
        println!("{name}");
    }
    println!("\nRemove Alex: {}", trie.remove("Alex"));
    println!("\nAutocomplete 'Al' after removal:");
    for name in trie.autocomplete("Al") {
        println!("{name}");
    }
    println!("\nContains Alex: {}", trie.contains("Alex"));
    println!("Contains Alexander: {}", trie.contains("Alexander"));
    println!("Number of names: {}", trie.len());
}

Тот же пример, но с применением готовой реализации Trie: crate trie-rs

crate trie-rs не поддерживает удаление узлов из существующего Trie. Что бы иметь возможность удалять узлы нам придется пересоздавать полностью всё дерево.

Причина в том, что trie-rs реализован не как обычное дерево из отдельных узлов с указателями. Он использует LOUDS — компактное представление дерева в битовых последовательностях, ориентированное на экономию памяти (минимальный расход памяти и быстрый поиск в неизменяемом дереве). API библиотеки рассчитан прежде всего на построение дерева и последующий поиск, а не на постоянное изменение его структуры т.е. после создания Trie добавлять и удалять узлы нельзя.


extern crate trie_rs;
use trie_rs::TrieBuilder;

fn main() {
    // Создаём Trie один раз.
    let mut builder = TrieBuilder::new();

    builder.push("Alice");
    builder.push("Alex");
    builder.push("Alexander");
    builder.push("Bob");
    builder.push("Charlie");

    let trie = builder.build();

    // Проверка полного совпадения.
    assert!(trie.exact_match("Alice"));
    assert!(!trie.exact_match("Al"));

    // Автодополнение по префиксу.
    let mut names: Vec<String> = trie.predictive_search("Al").collect();

    // Сортируем для предсказуемого вывода.
    names.sort();

    println!("Names starting with 'Al':");
    for name in names {
        println!("{name}");
    }
}

Output:

Names starting with 'Al':
Alex
Alexander
Alice

2. Longest Prefix Match

Смысл задачи такой: у нас есть несколько правил, и одно значение может подходить сразу под несколько правил. Нужно выбрать самое конкретное.

Найти самый длинный подходящий префикс. Классический пример — IP routing:

10.0.0.0/8
10.1.0.0/16
10.1.2.0/24

Что значит /8, /16, /24:

  • /8 → совпасть должна первая часть адреса (подходит всё, что начинается с 10)
  • /16 → первые две части (подходит всё, что начинается с 10.1)
  • /24 → первые три части (подходит всё, что начинается с 10.1.2)

Например для IP: 10.1.2.15 подходят все три маршрута, но нам нужен самый длинный совпавший prefix: 10.1.2 так как он более точно соответствует запрашиваемому IP

Trie хорошо подходщит для задачи поиска самого длинного маршрута. Мы идём по адресу постепенно и запоминаем последнее найденное правило:

10            ← найден маршрут /8
 ↓
10.1          ← найден маршрут /16
 ↓
10.1.2        ← найден маршрут /24
 ↓
10.1.2.15     ← дальше правила нет

Та же идея работает и для URL-правил:

/api
/api/users
/api/users/admin

В crate trie-rs для задачи поиска Longest Prefix Match, хорошо подходит common_prefix_search(), она возвращает все ключи Trie, которые являются префиксами запроса. Потом берём самый длинный из них.

В реальном коде используют структуры, которые работают с битовыми префиксами IP, например Patricia/Radix Trie или специализированные IP prefix crates. Но для понимания Longest Prefix Match через Trie этот пример показывает именно нужную механику.

extern crate trie_rs;
use trie_rs::TrieBuilder;

fn main() {
    let mut builder = TrieBuilder::new();

    builder.push("10");
    builder.push("10.1");
    builder.push("10.1.2");

    let trie = builder.build();

    let ip = "10.1.2.15";

    let longest_prefix = trie
        .common_prefix_search::<String, _>(ip)
        .max_by_key(|prefix| prefix.len()); // max_by_key выберет самый длинный путь

    match longest_prefix {
        Some(prefix) => {
            println!("IP: {ip}");
            println!("Самый длинный подходящий prefix: {prefix}");
        }
        None => {
            println!("Подходящий маршрут не найден");
        }
    }
}

Ouitput:

IP: 10.1.2.15
Самый длинный подходящий prefix: 10.1.2

3. URL routing

Например маршруты:

/api/users
/api/orders
/admin
/assets

Можно представить так:

root
├── api
│   ├── users
│   └── orders
├── admin
└── assets

Trie хранит не отдельные буквы, а части URL. Можно использовать Trie для поиска маршрутов по частям пути.

Trie-подобные структуры хорошо подходят для роутеров, особенно когда маршрутов очень много и у них общие части пути.

Например запрос: /api/users/123 подходит сразу под:

  • /api
  • /api/users

Но мы выбираем самый длинный: /api/users

extern crate trie_rs;
use trie_rs::map::TrieBuilder;

#[derive(Debug, Clone, Copy)]
enum Handler {
    Api,
    ListUsers,
    ListOrders,
    Admin,
    Assets,
}
fn main() {
    // Регистрируем маршруты.
    let mut builder = TrieBuilder::new();

    builder.push("/api", Handler::Api);
    builder.push("/api/users", Handler::ListUsers);
    builder.push("/api/orders", Handler::ListOrders);
    builder.push("/admin", Handler::Admin);
    builder.push("/assets", Handler::Assets);

    let routes = builder.build();

    // Обрабатываем запросы.
    dispatch(&routes, "/api/users");
    dispatch(&routes, "/api/users/123");
    dispatch(&routes, "/api/orders/500");
    dispatch(&routes, "/admin/settings");
    dispatch(&routes, "/assets/logo.png");
    dispatch(&routes, "/unknown");
}

fn dispatch(
    routes: &trie_rs::map::Trie<u8, Handler>,
    path: &str,
) {
    let matched = routes
        .common_prefix_search::<String, _>(path)
        .max_by_key(|(route, _)| route.len());

    match matched {
        Some((route, handler)) => {
            println!("Request: {path}");
            println!("Matched route: {route}");

            match handler {
                Handler::Api => {
                    println!("  -> API handler");
                }
                Handler::ListUsers => {
                    println!("  -> Listing users");
                }
                Handler::ListOrders => {
                    println!("  -> Listing orders");
                }
                Handler::Admin => {
                    println!("  -> Opening admin panel");
                }
                Handler::Assets => {
                    println!("  -> Serving static assets");
                }
            }
        }
        None => {
            println!("404 Not Found: {path}");
        }
    }
}

Output:

Request: /api/users
Matched route: /api/users
  -> Listing users
Request: /api/users/123
Matched route: /api/users
  -> Listing users
Request: /api/orders/500
Matched route: /api/orders
  -> Listing orders
Request: /admin/settings
Matched route: /admin
  -> Opening admin panel
Request: /assets/logo.png
Matched route: /assets
  -> Serving static assets
404 Not Found: /unknown