Исключение нарушения прав доступа при создании дерева AVL

Я пытаюсь создать идеально сбалансированное дерево AVL из вектора элементов. Я начал с небольшого количества элементов (8), чтобы проверить правильность алгоритма. Моя проблема возникает при печати значений из ДЕРЕВА, я продолжаю получать следующее исключение

"Exception thrown: read access violation.
nod->stanga was 0x4."

когда я добираюсь до (root)->(right)->left-:value, даже если я проверяю, является ли указатель нулевым, прежде чем что-либо печатать. структура:

typedef struct node
{   int key;
    int size;
    node *stanga;
    node *dreapta;
}TreeNode;

массив: int vector[8] = {1, 2, 3, 4, 5, 6, 7, 8}; функция печати:

void printElements(TreeNode *nod)
{
    if (nod != NULL)
    {
        printf("Nodul  este : %d \n", nod->key);
        if (nod->dreapta != NULL && nod->stanga != NULL)
        {
            printf("Nodul  dreapta al  nodului  %d este  : %d \n", nod->key, nod->dreapta->key);
            printf("Nodul  stamga al  nodului  este %d : %d\n ", nod->key, nod->stanga->key);

        }
        if (nod->dreapta != NULL)
        {
            printf("ramura dreapta a nodului  %d  cu valoare dreapta este : %d\n", nod->key,nod->dreapta->key);
            printElements(nod->dreapta);
        }
        if (nod->stanga != NULL)
        {
            printf("ramura dreapta a nodului  %d cu valoare stanga este : %d \n ",nod->key, nod->stanga->key);
            printElements(nod->stanga);
        }
    }
    else
    {
        printf("the end of the tree");
    }
}

вызывается с:

TreeNode  *nod = (TreeNode*)malloc(sizeof(TreeNode));
    nod=Build_tree(0, 7);
    printElements(nod);

build tree - это моя строительная функция:

TreeNode* Build_tree(int start, int end)
{

    if (start < end)
    {
        int medium = (start + end) / 2;
        TreeNode  *n1 = (TreeNode*)malloc(sizeof(TreeNode));
        n1->key = vector[medium];
        n1->size = 1;
        if (n1->stanga == NULL)
        {
            n1->size = n1->dreapta->size + 1;//alocam sizeul nodului din drepata
        }
        if (n1->dreapta == NULL)
        {
            n1->size = n1->stanga->size + 1;//altefl alocam sizeul nodului din stanga
        }

        n1->stanga = Build_tree(start, medium-1);
        n1->dreapta = Build_tree(medium+1,end);
        return n1;
    }

}

Я немного заржавел в использовании указателей и сбалансированных деревьев. Может ли кто-нибудь помочь мне с подсказкой?


person Diana G    schedule 24.04.2018    source источник
comment
Не знаю насколько актуально, но функция Build_tree не всегда возвращает значение. Если вы разместили вопрос, не заметив этого, возможно, есть и другие ошибки, которые вы также упустили из виду. Скомпилируйте со всеми включенными предупреждениями.   -  person Weather Vane    schedule 25.04.2018
comment
Почему он не всегда возвращает значение? по какому пути? (при отладке я могу смотреть только корневое значение и левое/правое от корневых значений, а не дальше (например, root -> левое-›левое))   -  person Diana G    schedule 25.04.2018
comment
Когда if (start < end) ложно. Если вы последуете моему совету и включите все предупреждения компилятора. . . Пожалуйста, сделайте это прямо сейчас.   -  person Weather Vane    schedule 25.04.2018
comment
включить все предупреждения компилятора, используя /w3#### в свойствах проекта?   -  person Diana G    schedule 25.04.2018
comment
Пожалуйста, посмотрите на функцию Build_tree. При выполнении блока кода if (start < end) функция возвращает n1. Если этот блок кода не выполняется, что возвращает функция? Посмотрите очень внимательно, это не имеет ничего общего с какой-либо постановкой задачи, а имеет отношение к путям управления.   -  person Weather Vane    schedule 25.04.2018
comment
он должен возвращать NULL или текущий узел. Я думаю?   -  person Diana G    schedule 25.04.2018


Ответы (1)


Оператор if (начало ‹ конец) в Build_tree имеет условие else, при котором вы теряете функцию, тем самым возвращая что-то неопределенное. Я вставил fprintf(stderr, «Ошибка: невозможно попасть сюда (%d,%d)\n», начало, конец) и получил следующий вывод:

Error: cannot get here (0, 0)
Error: cannot get here (2, 2)
Error: cannot get here (4, 4)
Error: cannot get here (6, 5)
Error: cannot get here (7, 7)
Nodul  este : 4 
Nodul  dreapta al  nodului  4 este  : 6 
Nodul  stamga al  nodului  este 4 : 2
 ramura dreapta a nodului  4  cu valoare dreapta este : 6
Nodul  este : 6 
ramura dreapta a nodului  6  cu valoare dreapta este : 7
Nodul  este : 7 
ramura dreapta a nodului  4 cu valoare stanga este : 2 
 Nodul  este : 2 

теперь, что должно быть сделано на другой стороне?

person mevets    schedule 24.04.2018
comment
Честно говоря, в алгоритме не упоминается продолжение оператора else. Я предполагаю, что это как-то связано с возвратом текущего узла, потому что, когда индексы были равны, я должен был просмотреть все числа в моем массиве. - person Diana G; 25.04.2018