Две вещи:
- у вас есть представление с прямой индексацией, вы не можете фактически удалить узлы из середины списка, вы можете установить их только на
"null"
(я бы предпочел рассмотреть используя null
, кстати) - в двоичном дереве поиска (независимо от его представления) удаление узла имеет несколько случаев в зависимости от его дочерних элементов
Если дочерних элементов нет, Вы можете просто удалить узел (null
это). Эта часть есть в вашем коде, просто она не должна быть remove()
:
if(leftChildStr.equals("null") && rightChildStr.equals("null"))
arr.set(i,"null"); // instead of arr.remove(i);
Если один дочерний элемент null
, другой должен быть перемещен вверх со всем своим поддеревом.
Я мог бы представить себе рекурсивную вспомогательную функцию для этого:
void moveup(ArrayList<String> arr,int from,int to){
if(from>=arr.size()){
arr.set(to,"null");
return;
}
String nodeString=arr.get(from);
arr.set(to,nodeString);
if(!nodeString.equals("null")){
moveup(arr,from*2+1,to*2+1);
moveup(arr,from*2+2,to*2+2);
}
}
(Это moveup
, потому что он не проверяет слишком большой to
и не пытается расширить список)
Тогда случаи (продолжая if
сверху):
else if(leftChildStr.equals("null"))
moveup(arr,rightChild,i);
else if(rightChildStr.equals("null"))
moveup(arr,leftChild,i);
И есть окончательный else
для обработки присутствия как левых, так и правых детей. Это сложно, на самом деле я не хочу думать об этом, но Википедия имеет некоторое представление:
Удаление узла с двумя детьми: вызовите удаляемый узел D. Не удаляйте D. Вместо этого выберите либо узел-предшественник по порядку, либо его узел-преемник по порядку в качестве узла замены E (см. рисунок). Скопируйте пользовательские значения E в D. [примечание 2] Если E не имеет дочернего элемента, просто удалите E из своего предыдущего родителя G. Если E имеет дочерний элемент, скажем F, это правильный дочерний элемент. Замените E на F у родителя E.
В сочетании с иллюстрацией:
Прежде всего, реализация этой идеи потребует реальной навигации в дерево, и, как указывает комментарий, вопрос показывает последовательный поиск в списке вместо двоичного поиска.