Странная проблема с указателями… построение BST с использованием массива указателей

0

Поэтому я пытаюсь создать BST с помощью массива указателей. Мой алгоритм верен (проверена версия, которая не использует указатели), но при использовании приведенного ниже кода происходит следующее:

  1. Если я добавлю первый элемент, он добавится в позицию 1 массива.
  2. Если я добавлю второй элемент, по какой-то причине позиция 1 массива будет перезаписана этому элементу, а затем программа продолжит (еще часть) и попытается снова вставить ее.

НАПРИМЕР. (проследил программу с кучей заглушек)

1. Call add(5, 1)
inserting 5 into position 1
position 1 is now 5

2. Call add(4, 1)
position 1 is now 4
moving right
inserting 4 into position 3
position 1 is now 4

...

template <typename Item> void ABTree<Item>::add(Item input, int index){
    if (array[1]==0){
        array[1] = &input;
        size++;
    }else{
        if (input < *array[index]){
            if (array[2*index] == 0){
                array[2*index] = &input;
                size++;
            }else
                add(input, 2*index);
        }else{
            if (array[(2*index)+1] == 0){
                array[(2*index)+1] = &input;
                size++;
            }else
                add(input, (2*index)+1);
    }
}
  • 0
    "if (array [0] == 0)"
  • 0
    Я хочу, чтобы array [1] был корнем BST, поэтому я всегда вызываю add с индексом 1.
Показать ещё 5 комментариев
Теги:
pointers
algorithm
binary-search-tree

2 ответа

0
Лучший ответ

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

if (array[1]==0){
    array[1] = input;
    size++;
}else{
    if (*input < *array[index]){
        if (array[2*index] == 0){
            array[2*index] = input;
            size++;
        }else
            add(input, 2*index);
    }else{
        if (array[(2*index)+1] == 0){
            array[(2*index)+1] = input;
            size++;
        }else
            add(input, (2*index)+1);
        }
}
0

В коде, который вы предоставили, есть целая проблема.

  1. Присвоение адреса временной переменной недопустимо. Переменная "input" заканчивается сразу после возврата функции add. Хранение его адреса, чем бессмысленно и приводит к почти неизбежному краху. В частности, когда вы добавляете второй элемент в свой массив, эти условия проверяют:

    • if (array [1] == 0)
    • if (input <* array [index])

    дает неопределенный результат и, следовательно, неопределенный поток управления.

  2. Я не знаю тип контейнера, который вы используете, но я предполагаю, что это будет своего рода векторный или даже простой массив C. Если мое предположение верно, вы должны выполнить проверку границ перед доступом к элементам массива с индексом.

  3. Выполнение перераспределения памяти, используемой массивом, не выполняется. Или, альтернативно, если вы используете массив с постоянным размером, проверка не выполняется (см. 2).

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

  • При проверке, что голова пуста - false;
  • На проверке if (input <* array [index]) - false, поскольку массив [index] содержит мусор, поэтому "вставка 4 в позицию 3", несмотря на то, что мы должны добавить 4 в позицию 2;
  • В чеке if (array [(2 * index) +1] == 0) - снова false, так как этот элемент содержит мусор тоже (правильно ли вы, что вы не инициализировали массив с нулями?);
  • Таким образом, происходит рекурсивный вызов процедуры добавления...
  • 0
    Я не верю, if (array[1]==0) приведет к неопределенному поведению. Память по адресу может больше не быть доступной, но это не означает, что переменная, хранящая сам адрес, недоступна или что ее значение изменилось, поскольку память больше недоступна.
  • 0
    Что-то вроде. При второй вставке заголовок перезаписывается на новое значение для вставки, поэтому, когда выполняется проверка «if (input <* array [index])», он возвращает false, поэтому вставка в позиции 3.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню