Помоги мне, пожалуйста, создать метод, который бы по ключу находил значение. В моём классе реализована работа с ассоциативным массивом в персистентном виде:
#ifndef PERSISTENT_ASSOCIATIVE_ARRAY_H
#define PERSISTENT_ASSOCIATIVE_ARRAY_H

#include <iostream>
#include <vector>
#include <memory>
#include <utility>

template <typename KeyType, typename ValueType>
struct AA_node
{
    KeyType key{};
    ValueType value{};
    std::shared_ptr<AA_node<KeyType, ValueType>> left{};
    std::shared_ptr<AA_node<KeyType, ValueType>> right{};

    AA_node(KeyType k, ValueType v) : key(k), value(v), left(nullptr), right(nullptr) {}
};

template <typename KeyType, typename ValueType>
class PersistentAssociativeArray {
private:
    std::vector<std::shared_ptr<AA_node<KeyType, ValueType>>> versions{};

    std::shared_ptr<AA_node<KeyType, ValueType>> insert(std::shared_ptr<AA_node<KeyType, ValueType>> root, KeyType key, ValueType value) {
        if (!root) {
            return std::make_shared<AA_node<KeyType, ValueType>>(key, value);
        }

        if (key < root->key) {
            root->left = insert(root->left, key, value);
        }
        else if (key > root->key) {
            root->right = insert(root->right, key, value);
        }
        else {
            root->value = value; // Обновляем значение при совпадении ключа
        }
        //std::cout << root->value << "\t";
        return root; // Возвращаем корень для использования
    }

    // Рекурсивная функция для копирования дерева
    std::shared_ptr<AA_node<KeyType, ValueType>> copyTree(std::shared_ptr<AA_node<KeyType, ValueType>> root) {
        if (!root) {
            return nullptr;
        }
        auto newNode = std::make_shared<AA_node<KeyType, ValueType>>(root->key, root->value);
        newNode->left = copyTree(root->left);
        newNode->right = copyTree(root->right);
        return newNode;
    }

    // Рекурсивная функция для печати узлов
    void printNodes(std::shared_ptr<AA_node<KeyType, ValueType>> root) {
        if (!root) {
            return;
        }
        //printNodes(root->left);  // Печатаем левое поддерево
        //std::cout << "'" << root->key << "':" << root->value << ", "; // Печатаем текущий узел
        //printNodes(root->right); // Печатаем правое поддерево
        std::cout << "'" << root->key << "': " << root->value;

        // Печатаем запятую, если у нас есть правый под узел
        if (root->right) {
            std::cout << ", ";
        }

        printNodes(root->left);
        printNodes(root->right);
    }

    int current_version{};

    std::vector<KeyType> keys;

public:
    PersistentAssociativeArray(const std::vector<KeyType>& keys, ValueType* values_array, size_t values_array_size) 
    {
        if (keys.size() != values_array_size || keys.empty()) 
        {
            throw std::invalid_argument("Keys and values must have the same non-zero length.");
        }

        std::shared_ptr<AA_node<KeyType, ValueType>> root = nullptr; // Строка, с которой вы сказали, что проблема

        for (size_t i = 0; i < keys.size(); ++i) 
        {
            root = insert(root, keys[i], values_array[i]);
            std::cout << "\n";
        }

        versions.push_back(root);

        current_version = 0;

        this->keys = keys;
    }

    // Функция для добавления новой версии с изменением значения
    void addVersion(int root_position, KeyType change_key, ValueType new_value) {
        if (current_version < 0 || current_version >= versions.size() ||
            root_position < 0 || root_position >= versions.size()) {
            throw std::out_of_range("Invalid root position");
        }

        // Копируем дерево по указанной версии
        auto new_root = copyTree(versions[root_position]);

        // Вставляем новое значение в скопированное дерево
        insert(new_root, change_key, new_value); std::cout << "\n";

        // Добавляем новую версию в вектор
        versions.push_back(new_root);

        current_version++;
    }

    // Тестовая функция для вывода
    void print() {
        for (const auto& version : versions) {
            // Печать информации о каждом узле
            std::cout << "Version root key: " << version->key << ", value: " << version->value << std::endl;
        }
    }

    // Method to make UNDO-action
    void undo()
    {
        if (current_version <= 0)
        {
            std::cout << "No actions to undo!" << std::endl;
            return;
        }

        current_version--;
        versions.push_back(versions[current_version]);
    }

    // Method to make REDO-action
    void redo()
    {
        if (current_version >= versions.size() - 1) {
            std::cout << "No actions to redo!" << std::endl;
            return;
        }

        current_version++;  // Переход к следующей версии
        versions.push_back(versions[current_version]);
    }

    // Функция для печати всех версий
    void printAllVersions() {
        for (size_t i = 0; i < versions.size(); ++i) {
            std::cout << "Version [" << i << "]\t";
            std::cout << "{";
            printNodes(versions[i]);
            std::cout << "}" << std::endl; // Разделяем версии пустой строкой
        }
    }

    void printInInsertionOrder() {
        for (const auto& version : versions) {
            printNodes(version);  // Печатаем узлы данной версии
            std::cout << std::endl; // Разделяем версии пустой строкой
        }
    }
};

#endif // PERSISTENT_ASSOCIATIVE_ARRAY_H