【问题标题】:Updating parent node in Binary search tree in JAVA在JAVA中更新二叉搜索树中的父节点
【发布时间】:2014-02-03 06:55:36
【问题描述】:

我正在研究二叉搜索树,在更新/添加当前节点的父节点时遇到了一些问题。父节点没有正确更新。这就是我想要做的:

public class binarytree {

    private Node root;

static class Node{

    Node left;
    Node right;
    int value;
    Node parent;

    public Node(Node parent,int value)
        {
        this.value = value;
        this.left = null;
        this.right = null;
        this.parent = parent;
        }
    }

public void creatBST()
    {
    root = new Node(null,4);
    System.out.println("Binary Search tree with root = "+ root.value);
    insert(root,1);
    insert(root,2);
    insert(root,3);
    insert(root,6);
    insert(root,5);
    insert(root,7);
}

public void insert(Node node, int value)
    {
    Node prevnode = node;
    if(value < node.value)
        {
        if(node.left != null)
            {


            insert(node.left, value);   
            System.out.println("Parent node of node"+ node.left.value+"is:"+prevnode.value);
            }
        else
            {

            node.left = new Node(prevnode,value);
            }
        }
    else if(value > node.value)
        {
        if(node.right != null)
            {
            //prevnode = node;

            insert(node.right, value);
            System.out.println("Parent node of node"+ node.right.value+"is:"+prevnode.value);
            }
        else
            {

            node.right = new Node(prevnode,value);
            }
        }
    }
public static void main(String args [])
    {
    binarytree obj = new binarytree();
    obj.creatBST();
    //obj.printInOrder();
    //obj.check();
    }
}

我得到的输出是:

    Binary Search tree with root = 4
Parent node of node1is:4
Parent node of node2is:1
Parent node of node1is:4
Parent node of node6is:4
Parent node of node6is:4

这不是正确的输出。

需要帮助我确定如何正确执行此操作。

【问题讨论】:

  • 这个我没太认真研究过,不过貌似leftright是左右孩子。如果是这种情况,我们应该总是有node.left.parent==nodenode.right.parent==node(对于非空子),对吗?但是在node.right = new Node(prevnode,value); 之后,那么node.right.parent 就是prevnode,这似乎违反了那个不变量。同样,我没有尝试过或详细研究过它,所以也许那个代码是可以的。但它看起来很奇怪。
  • @ajb prevnode 每次调用 insert() 时都会用 node 初始化。那么,在 insert() 中 prevnode 和 node 的值不应该相同吗?
  • 看来你是对的。就像我说的,我没有详细研究代码。但是有一个单独的prevnode 变量,其唯一目的似乎是保持与node 相同的值,有点令人困惑。有没有理由拥有prevnode
  • 我只是尝试将父节点添加到每个节点,以便我可以进行一些额外的处理,例如查找中序继任者。为此,我创建了 prevnode 变量来表示每个节点的父节点

标签: java binary-search-tree


【解决方案1】:

看起来节点的插入工作正常。 print 语句是错误的,因为它们是在递归调用插入下一个节点之后调用的。例如,在您执行 insert(root,1) 之后,您的函数可以工作并且您具有以下结构:

          4
         /
        1

现在,当您调用 insert(root, 2) 时,您将在代码中的这一点结束:

if(node.left != null)
        {


        insert(node.left, value);   
        System.out.println("Parent node of node"+ node.left.value+"is:"+prevnode.value);
        }

insert(node.left, value) 被调用,然后打印语句发生。所以虽然你的新树看起来像这样:

          4
         /
        1
         \
          2

下一个打印语句

        System.out.println("Parent node of node"+ node.left.value+"is:"+prevnode.value);

将打印出 node.left.value 为 1 和 prevnode.value 为 4。您可能想要更改打印语句的位置或编写一个打印节点和父节点的新方法。

编辑: 我会在你的 main 方法中运行这个方法来测试树结构:

    public void printParents(Node n){
    if(n.left!= null){
        printParents(n.left);
    }
    if(n.right!=null){
        printParents(n.right);
    }
    if(n.parent != null){
        System.out.println("Parent of " + n.value + " is " + n.parent.value);
    }
    else{
        System.out.println("The root node is" + n.value);
    }
}

我在这里调用它:

public static void main(String args [])
{
binarytree obj = new binarytree();
obj.creatBST();
Node n = obj.root;
obj.printParents(n);
//obj.printInOrder();
//obj.check();
}

【讨论】:

  • 我添加了打印语句来检查父节点更新是否正确完成。我应该把它们放在哪里,以便我知道父节点是否正确更新?
  • @user2916886 查看我刚刚添加的内容。我认为这可能会对您有所帮助。
  • 非常感谢@user3088847!看起来错误是只打印父节点而不是添加它。
【解决方案2】:

对于初学者,您可能需要修复插入方法:

Node currentNode;
public void setCurrentNode(Node node) {
    currentNode = node;
}

public boolean insert(int value) {
    //You should probably insert from an instance variable, not an explicit parameter
    Node n = new Node(currentNode, value);
    if (currentNode.left == null) currentNode.left = n;
    else if (currentNode.right == null) currentNode.right = n;
    else return false;    //If insert failed because currentNode was full
    return true;
}

【讨论】:

  • 我不认为我的插入功能有问题。当我做任何遍历输出时,节点被正确插入。但问题是我无法更新正确的父字段,我需要进行其他一些处理。
  • 注意变量的声明和更改位置。如果它们是显式参数,请不要更改方法中的变量。
猜你喜欢
  • 1970-01-01
  • 2015-08-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多