【问题标题】:Find predecessor and successor of a binary search tree in java在java中查找二叉搜索树的前任和后继
【发布时间】:2018-02-06 09:35:33
【问题描述】:

我的项目要我打印出二叉搜索树的前任和后继。分配要求我将节点的数据作为参数传递。当我尝试打印出给定节点数据的前身时,它给了我0。我不知疲倦地尝试如何解决问题,但没有找到。希望你能找到问题所在。

方法如下:

  public void findPredecessor(Node root, int data)
  {
    int predecessor = 0;
    if(root != null)
    {
        if(root.data == data)
        {
            if(root.left != null)
            {
                Node n = root.left;
                while(n.right != null) n = n.right;
                predecessor=  n.data;
            }
        }
        else if(root.data < data)
        {
            predecessor = root.data;
            findPredecessor(root.left, data);
        }
    }
    System.out.print(predecessor);
}

public void printPredecessor(int data)
{
    findPredecessor(root, data);
}

【问题讨论】:

标签: java tree binary-tree binary-search-tree


【解决方案1】:

这是我认为正确方法的伪代码:

Input: root node,key | output: predecessor node, successor node 
  • 如果root为NULL则返回

  • 如果找到密钥然后

    a. If its left subtree is not null Then predecessor will be the right
       most child of left subtree or left child itself i.e maximum value
       in left subtree 
    
    b. If its right subtree is not null Then successor will be the lefmost 
       child of right subtree or right child itself i.e minimum value in 
       right subtree.
    

    返回

  • 如果 key小于root节点将后继节点设置为root
    并递归搜索左子树

    else 将前任设置为根并递归搜索 右子树

编辑:如果后继或前任返回 null 打印 null。

示例

                         (1)<--root
                            \
                              \
                               (3)
                               /
                              /
                           (2)<--targetKey
Initially,
 successor=null
 predecessor=null

 FunctionCall(root,successor,predecessor,targetKey):

         Here root's key is smaller than target key so,
         Set predecessor=root.

                          (1)   <--predecessor
                            \
                              \
                               (3)
                               /
                              /
                           (2)<--targetKey


         //Search recursively in right subtree
     FunctionCall(root.right,successor,predecessor,targetKey):

              Here root's key is greater than target key so,
         Set successor=root.
                          (1) <--predecessor
                            \
                              \
                               (3) <--successor
                               /
                              /
                           (2)<--targetKey

           //Search recursively in left subtree
     FunctionCall(root.left,successor,predecessor,targetKey):

               Root.key==targetKey
                 Also,
                Root.right==null
                Root.left==null
            Return

  Successor=3
  Predecessor=1

希望对你有帮助!

【讨论】:

  • 如果找到了key,左子树为null怎么办?你把那个案子放在一边了。
  • 但是如何找到前任呢? (P.S. 如果你在回复我发布后编辑的更大版本的评论,对不起——那是我的错。)
  • 我们还可以检查返回的后继或前驱是否为空。
  • 如果整个树的根等于键,这将起作用。但不是当你递归下降时。试试这个:你有三个节点,1、3、2。节点 1 的右链接指向节点 3。节点 3 的左链接指向节点 2。找到 2 的前任。你的算法将不起作用。它可能会起作用,而您只是写得不好。如果是这种情况,请继续填写缺失的详细信息。
  • 我认为您没有获得代码,在您的情况下,它将执行密钥小于或大于根密钥的第三部分。在您的情况下,答案将是 prede:1,successor:3。
【解决方案2】:

您可以使用 inOrder 遍历在二叉搜索树中找到节点的前驱和后继。 inOrder 遍历的基本结构是:

inOrder(Node n)
  if (n == null) return;
  inOrder(n.left)
  visit(n)
  inOrder(n.right)

在这种情况下,当我们访问一个节点时,我们希望根据我们已经看到的来跟踪前驱节点、匹配节点和后继节点。基本逻辑如下:

visit(n)
  if n.val == searchVal
    match = n
  else if match == null
    predecessor = n
  else if successor == null
    successor = n;

这里有一些 Java 代码。我正在使用一个简单的 3 元素数组来存储前任、匹配和后继。

class Node
{
  int val;
  Node left, right;
}

static void inOrder(Node n, int val, Node[] seq)
{
  if(n == null) return;

  inOrder(n.left, val, seq);

  if(n.val == val) 
    seq[1] = n;
  else if(seq[1] == null)
    seq[0] = n;
  else if(seq[2] == null)
    seq[2] = n;

  inOrder(n.right, val, seq);   
}

public static void main(String[] args)
{
  Node root = buildTree();
  int searchVal = Integer.parseInt(args[0]);

  Node[] seq = new Node[3];
  inOrder(root, searchVal , seq);
  System.out.println("Predecessor: " + seq[0]);
  System.out.println("Match: " + seq[1]);
  System.out.println("Successor: " + seq[2]);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-06-11
    • 1970-01-01
    • 2017-04-25
    • 1970-01-01
    • 2011-07-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多