Реализация операции вставки двоичного дерева поиска в Java

У меня есть класс TreeNode, представляющий узел двоичного дерева.

public class TreeNode {

private static Object key=null;
private static Object value=null;
private TreeNode parent;
private TreeNode left=null;
private TreeNode right=null;    
/**
 * @return the value
 */
public static Object getValue() {
    return value;
}

/**
 * @param aValue the value to set
 */
public static void setValue(Object aValue) {
    value = aValue;
}


public TreeNode()
{
    this(key,value);
}
public TreeNode(Object key,Object value)
{
    this.key = key;
    this.value = value;
}
/**
 * @return the key
 */
public Object getKey() {
    return key;
}

/**
 * @param key the key to set
 */
public void setKey(Object key) {
    this.key = key;
}

/**
 * @return the parent
 */
public TreeNode getParent() {
    return parent;
}

/**
 * @param parent the parent to set
 */
public void setParent(TreeNode parent) {
    this.parent = parent;
}

/**
 * @return the left
 */
public TreeNode getLeftChild() {
    return left;
}

/**
 * @param left the left to set
 */
public void setLeftChild(TreeNode left) {
    this.left = left;
}

/**
 * @return the right
 */
public TreeNode getRightChild() {
    return right;
}

/**
 * @param right the right to set
 */
public void setRightChild(TreeNode right) {
    this.right = right;
}

}

У меня есть класс BinarySearchTree

public class BinarySearchTree implements DataStructures.interfaces.BinarySearchTree {
private int size=0;
private TreeNode root = new TreeNode();

@Override
public void insert(Object key, Object value)
{
    insertOperation(key,value,root);
}

private void insertOperation(Object element, Object value, TreeNode node)
{

    if(node.getKey() == null) {
        node.setKey(element);
        node.setValue(value);            
    }
    else
    {
        if((int) node.getKey() > (int) element)
        {
            if(node.getLeftChild() != null)
                insertOperation(element,value,node.getLeftChild());
            else
            {
                TreeNode child = new TreeNode(element, value);
                child.setKey(element);
                child.setValue(value);
                child.setParent(node);
                node.setLeftChild(child);

                size++;
            }
        }
        else if((int) node.getKey() <= (int) element)
        {
            if(node.getRightChild() != null)
                insertOperation(element,value,node.getRightChild());
            else
            {
                TreeNode child = new TreeNode(element, value);
                child.setKey(element);
                child.setValue(value);
                child.setParent(node);
                node.setRightChild(child);

                size++;
            }
        }
    }

  }
  ///more methods
}

Проблема в том, что когда я создаю дочерний узел и устанавливаю родительскую дочернюю ссылку. Значение родительского узла (объект узла, который я передал) также обновляется и ссылается на дочерний объект.

Это не мое намерение.

Я хочу создать цепочку объектов treenode, к которым можно получить доступ через «корневой» объект treenode.

Но этого не происходит и я не понимаю, что я делаю не так.

Я знаю, что проблема заключается в логике этого фрагмента кода (не только для вставки слева, но и для вставки левого потомка и правого), но я не понимаю, что именно.

           if(node.getLeftChild() != null)
                insertOperation(element,value,node.getLeftChild());
            else
            {
                TreeNode child = new TreeNode(element, value);
                child.setKey(element);
                child.setValue(value);
                child.setParent(node);
                node.setLeftChild(child);

                size++;
            }

Все, что я говорю java, это если у рассматриваемого узла нет левого дочернего элемента, тогда создайте левый дочерний узел и установите левый объект текущего узла в дочерний объект.

если у рассматриваемого узла есть левый дочерний элемент, проверьте этот дочерний элемент и посмотрите, должен ли новый узел быть вставлен слева или справа, вызвав ту же функцию для дочернего элемента рассматриваемого узла... Я не понимаю, почему узел (передан объект TreeNode) ключ обновляется, когда я устанавливаю значение дочернего ключа.


person anu    schedule 30.10.2013    source источник
comment
Вы должны показать свои методы setParent и set*Child, чтобы быть уверенным.   -  person NG.    schedule 30.10.2013
comment
@СБ. Я добавил методы установки и получения.   -  person anu    schedule 30.10.2013


Ответы (2)


Почему ваши key и value статические объекты? Это означает, что все TreeNodes будут иметь один и тот же ключ/значение. Удалите статическое ключевое слово, и все должно работать нормально.

person Worakarn Isaratham    schedule 30.10.2013
comment
И также удалите static из геттера и сеттера в treeNode. - person GregHNZ; 30.10.2013
comment
Ага, только сейчас понял! Спасибо. Запоздалая ошибка. - person anu; 30.10.2013

Я не совсем понимаю, что вы имеете в виду под

Проблема в том, что когда я создаю дочерний узел и устанавливаю родительскую дочернюю ссылку. Значение родительского узла (объект узла, который я передал) также обновляется и ссылается на дочерний объект.

но я заметил одну вещь, которая приведет к ошибке:

    else if((int) node.getKey() <= (int) element)

Когда node.getKey() == element, это означает, что в bst уже есть узел с «элементом» в качестве ключа, что должно быть еще одним особым случаем. Вместо этого вы все еще проходите через его правого потомка.

Кроме того, было бы неплохо, если бы вы могли уточнить свою ошибку более четко...

person yfan    schedule 30.10.2013
comment
Хорошая точка зрения. Я уберу тот и другой случай, запрещающий вставку дубликатов ключей. Проблема заключалась в том, что когда я создал новый дочерний объект класса TreeNode, атрибуты ключа и значения корневого объекта изменились на ключ и значение дочернего элемента. Причиной этого было то, что мои атрибуты ключа и значения были статическими. Таким образом, все объекты имеют одни и те же статические значения. Моя IDE предупредила меня об этом, но я проигнорировал это. Теперь я понимаю, как важно прислушиваться к предупреждениям. - person anu; 30.10.2013
comment
Ха-ха. Я понимаю. Иногда они раздражают, но в большинстве случаев они полезны. Удачи =) @Anupam - person yfan; 30.10.2013