Есть АВЛ-дерево. Каждый элемент хранит хеш-таблицу и ключ, по которому он сравнивается с другими элементами и добавляется в дерево. Тестовая ситуация такая: 1)добавлен элемент с ключом milk, он корневой; 
2)добавлен элемент с ключом bread, он меньше milk, поэтому становится левым поддеревом, корневым остаётся milk, у milk balance = -1, у bread balance = 0; 
3)добавлен элемент с ключом butter, он меньше milk, но больше bread, поэтому становится слева от milk и справа от bread, выполняется балансировка, корневым становится butter, слева bread, справа milk, переменная balance у всех трёх равна 0; 
4)удалён элемент butter, корневым становится меньший, то есть bread; снова добавлен элемент butter. 
По идее, должна выполниться балансировка и корневым должен стать butter, но этот статус по какой-то причине остаётся у bread. То есть корневой bread, справа от него milk и слева от него butter. Переменная balance у butter = 0, у milk = -1, и у bread = 1. Должен стать корневым butter, слева bread, справа milk, и переменная balance у всех трёх должна быть = 0. Попытайся исправить, используя эту информацию. Функции добавления изначально работают нормально, проблема в функциях удаления. Вот код класса tree: class Tree 
{
private:
    
    std::vector<Sorts> readFromFile(const std::string& filename) {
        std::vector<Sorts> sorts;
        std::ifstream file(filename);

        if (file.is_open()) {
            int vc;
            std::string pn;
            long long int t;
            int day;
            int month;
            int year;


            while (file >> vc >> pn >> t >> day >> month >> year) {
                VendorCode vendorcode(vc);
                ProductName productname(pn);
                TIN tin(t);
                Date date(day, month, year);

                sorts.push_back(Sorts(vendorcode, productname, tin, date));
            }

            file.close();
        }
        else {
            std::cerr << "Enable open file" << filename << std::endl;
        }

        return sorts;
    }
    void add(int vc, std::string pn, long long int t, int d, int m, int y, Node*& p, bool& h, int htsize) // поиск и добавление элемента
    {
        VendorCode vendorcode(vc);
        ProductName productname(pn);
        TIN tin(t);
        Date date(d, m, y);
        Sorts s(vendorcode, productname, tin, date);
        if (p == NULL) // слова нет в дереве; включить его
        {
            p = new Node;
            h = true;
            p->key = s.productnames.productname;
            p->ht.changeSize(htsize);
            p->ht.insertItem(s);
            p->balance = 0;
            p->left = NULL;
            p->right = NULL;
        }
        else if (pn < p->key)
        {
            add(vc, pn, t, d, m, y, p->left, h, htsize);
            if (h) // выросла левая ветвь
            {
                switch (p->balance)
                {
                case 1:
                    p->balance = 0;
                    h = false;
                    break;
                case 0:
                    p->balance = -1;
                    break;
                case -1: // балансировка
                    Node * p1 = p->left;
                    if (p1->balance == -1) // L-поворот
                    {
                        p->left = p1->right;
                        p1->right = p;
                        p->balance = 0;
                        p = p1;
                    }
                    else // LR-поворот
                    {
                        Node* p2 = p1->right;
                        p1->right = p2->left;
                        p2->left = p1;
                        p->left = p2->right;
                        p2->right = p;
                        if (p2->balance == -1)
                            p->balance = 1;
                        else
                            p->balance = 0;
                        if (p2->balance == 1)
                            p1->balance = -1;
                        else
                            p1->balance = 0;
                        p = p2;
                    }
                    p->balance = 0;
                    h = false;
                    break;
                }
            }
        }
        else if (pn > p->key)
        {
            add(vc, pn, t, d, m, y, p->right, h, htsize);
            if (h == true) // выросла правая ветвь
            {
                switch (p->balance)
                {
                case -1:
                    p->balance = 0;
                    h = false;
                    break;
                case 0:
                    p->balance = 1;
                    break;
                case 1: // балансировка
                    Node * p1 = p->right;
                    if (p1->balance == 1) //R-поворот
                    {
                        p->right = p1->left;
                        p1->left = p;
                        p->balance = 0;
                        p = p1;
                    }
                    else // RL-поворот
                    {
                        Node* p2 = p1->left;
                        p1->left = p2->right;
                        p2->right = p1;
                        p->right = p2->left;
                        p2->left = p;
                        if (p2->balance == 1)
                            p->balance = -1;
                        else
                            p->balance = 0;
                        if (p2->balance == -1)
                            p1->balance = 1;
                        else
                            p1->balance = 0;
                        p = p2;
                    }
                    p->balance = 0;
                    h = false;
                    break;
                }
            }
        }
        else
        {
            p->ht.insertItem(s);
            h = false;
        }
    }
    void balance1(Node* p, bool& h)
    {
        Node* p1, * p2;
        short b1, b2;
        switch (p->balance)
        {
        case -1:
            p->balance = 0;
            break;
        case 0:
            p->balance = 1;
            h = false;
            break;
        case 1: // балансировка
            p1 = p->right;
            b1 = p1->balance;
            if (b1 >= 0) // R-поворот
            {
                p->right = p1->left;
                p1->left = p;
                if (b1 == 0)
                {
                    p->balance = 1;
                    p1->balance = -1;
                    h = false;
                }
                else
                {
                    p->balance = 0;
                    p1->balance = 0;
                }
                p = p1;
            }
            else // RL-поворот
            {
                p2 = p1->left;
                b2 = p2->balance;
                p1->left = p2->right;
                p2->right = p1;
                p->right = p2->left;
                p2->left = p;
                if (b2 == 1)
                    p->balance = -1;
                else
                    p->balance = 0;
                if (b2 == -1)
                    p1->balance = 1;
                else
                    p1->balance = 0;
                p = p2;
                p2->balance = 0;
            }
        }
    }
    void balance2(Node* p, bool& h)
    {
        Node* p1, * p2;
        short b1, b2;
        switch (p->balance)
        {
        case 1:
            p->balance = 0;
            break;
        case 0:
            p->balance = 0;
            h = false;
            break;
        case -1:
            p1 = p->left;
            b1 = p1->balance;
            if (b1 <= 0) // L-поворот
            {
                p->left = p1->right;
                p1->right = p;
                if (b1 == 0)
                {
                    p->balance = -1;
                    p1->balance = 1;
                    h = false;
                }
                else
                {
                    p->balance = 0;
                    p1->balance = 0;
                }
                p = p1;
            }
            else // LR-поворот
            {
                p2 = p1->right;
                b2 = p2->balance;
                p1->right = p2->left;
                p2->left = p1;
                p->left = p2->right;
                p2->right = p;
                if (b2 == -1)
                    p->balance = 1;
                else
                    p->balance = 0;
                if (b2 == 1)
                    p1->balance = -1;
                else
                    p1->balance = 0;
                p = p2;
                p2->balance = 0;
            }
        }
    }
    Node* del(Node* r, Node* q, bool& h)
    {
        if (r->right != NULL)
        {
            r->right = del(r->right, q, h);
            if (h)
                balance2(r, h);
            return r;
        }
        else
        {
            q->key = r->key;
            Node* left = r->left;
            delete r;
            h = true;
            return left;
        }
    }

    void delet(std::string pn, int d, int m, int y, Node*& p, bool& h) // удаление элемента, выше вспомогательные подпрограммы
    {
        Node* q;
        if (p == NULL)
        {
            h = false;
        }
        else if (pn < p->key)
        {
            delet(pn, d, m, y, p->left, h);
            if (h)
                balance1(p, h);
        }
        else if (pn > p->key)
        {
            delet(pn, d, m, y, p->right, h);
            if (h)
                balance2(p, h);
        }
        else
        {
            if (p->left == NULL && p->right == NULL)
            {
                p->ht.removeItem(d, m, y);
                if (p->ht.isEmpty())
                {
                    delete p;
                    p = NULL;
                    h = true;
                }
            }
            else if (p->left != NULL && p->right == NULL)
            {
                p->ht.removeItem(d, m, y);
                if (p->ht.isEmpty())
                {
                    Node* temp = p->left;
                    delete p;
                    p = temp;
                    h = true;
                }
            }
            else if (p->left == NULL && p->right != NULL)
            {
                p->ht.removeItem(d, m, y);
                if (p->ht.isEmpty())
                {
                    Node* temp = p->right;
                    delete p;
                    p = temp;
                    h = true;
                }
            }
            else
            {
                p->ht.removeItem(d, m, y);
                if (p->ht.isEmpty())
                {
                    Node* temp = p->left;
                    Node* parent = p;
                    while (temp->right != NULL)
                    {
                        parent = temp;
                        temp = temp->right;
                    }
                    if (parent != p)
                        parent->right = temp->left;
                    else
                        parent->left = temp->left;
                    p->key = temp->key;
                    p->ht = temp->ht;
                    delete temp;
                    h = true;
                }
            }
        }
    }
    void print(Node* t, short hh) // печать дерева
    {
        if (t != NULL)
        {
            print(t->right, hh + 1);
            for (int i = 1; i <= hh; i++)
                cout << "   ";
            t->ht.printTable(t->key);
            std::cout << endl;
            print(t->left, hh + 1);
        }
    }
    void walk(Node* t, short hh, std::ofstream& out) // обход дерева справа налево и вывод в файл
    {
        if (t != NULL)
        {
            walk(t->right, hh + 1, out);
            t->ht.writeFile(out, t->key);
            walk(t->left, hh + 1, out);
        }
    }
    void search(std::string pn, int d, int m, int y, Node*& p, bool& h, int searchsteps) // поиск элемента
    {
        Node* q;
        if (p == NULL)
        {
            cout << "Haven't found." << endl;
            h = false;
        }
        else if (pn < p->key)
        {
            searchsteps++;
            search(pn, d, m, y, p->left, h, searchsteps);
        }
        else if (pn > p->key)
        {
            searchsteps++;
            search(pn, d, m, y, p->right, h, searchsteps);
        }
        else
        {
            searchsteps = p->ht.searchItem(d, m, y,searchsteps);
            if (searchsteps == -1)
                std::cout << "Haven't found." << std::endl;
            else
                std::cout << "Found in " << searchsteps << " steps." << std::endl;
            h = false;
        }
    }
public:
    Node* root;
    void addItem(int vc, std::string pn, long long int t, int d, int m, int y, int htsize)
    {
        bool h = false;
        add(vc, pn, t, d, m, y, root, h, htsize);
    }

    void removeItem(std::string pn, int d, int m, int y)
    {
        bool h = false;
        delet(pn, d, m, y, root, h);
    }

    void searchItem(std::string pn, int d, int m, int y)
    {
        bool h = false;
        search(pn, d, m, y, root, h, 0);
    }

    void printTree()
    {
        print(root, 0);
    }

    void writeFile(std::string file)
    {
        std::ofstream out(file);
        walk(root, 0, out);
    }

    Tree(const std::string readFile, int n, int htsize)
    {
        root = NULL;
        std::vector <Sorts> sorts = readFromFile(readFile);

        for (int i = 0; i < n; i++)
        {
            if (i < sorts.size())
                addItem(sorts[i].vendorcodes.vendorcode, sorts[i].productnames.productname, sorts[i].tins.tin, sorts[i].dates.day, sorts[i].dates.month, sorts[i].dates.year, htsize);
        }
    }
};