我正在try 创建一个移除方法,从AVL树中移除一个 node .但是测试我的代码的程序给了我一个错误,说我没有正确使用NoSuchElementException.

下面是我的Remove方法(和emoveRecursive方法)的代码.

    public T remove(T data) {
        // Base case: if data is null, throw an exception
      if (data == null) {
         throw new IllegalArgumentException("Error: data cannot be null.");
      }
   
        // Recursive helper method for removing data from the tree
      AVLNode<T> removedNode = removeRecursive(root, data);
   
        // If the node is not found, throw NoSuchElementException
      if (removedNode == null) {
         throw new NoSuchElementException("Error: data not found in the tree.");
      }
   
        // Update the root after removal
      root = removedNode;
   
      return removedNode.getData();
   }
   
   private AVLNode<T> removeRecursive(AVLNode<T> current, T data) {
      if (current == null) {
         return null; // Data not found
      }
   
      // Compare data with the current node's data
      int compareResult = data.compareTo(current.getData());
   
      if (compareResult < 0) {
        // Data is smaller, go to the left subtree
         current.setLeft(removeRecursive(current.getLeft(), data));
      } else if (compareResult > 0) {
        // Data is larger, go to the right subtree
         current.setRight(removeRecursive(current.getRight(), data));
      } else {
        // Node with data found, perform removal based on cases
      
         if (current.getLeft() == null && current.getRight() == null) {
            // Case 1: Node is a leaf (no children)
            size--;
            return null;
         } else if (current.getLeft() != null && current.getRight() != null) {
            // Case 3: Node has two children
            // Replace the data with the successor's data
            AVLNode<T> successor = findSuccessor(current.getRight());
            current.setData(successor.getData());
            // Remove the successor node
            current.setRight(removeRecursive(current.getRight(), successor.getData()));
         } else {
            // Case 2: Node has one child
            size--;
            return (current.getLeft() != null) ? current.getLeft() : current.getRight();
         }
      }
   
      // Update height and balance factor, then balance the tree
      return balance(current);
   }

这就是它给我的错误:

[测试失败:删除]:try 删除树以外的数据时未引发NoSuchElementException.

我很困惑,因为我在判断RemvedNode是否为空时抛出了NoSuchElementException.那么,为什么它说它没有被扔出go 呢?谢谢.

不知道还能试什么.另外,我已经试过调试这个程序,但它仍然显示相同的内容.

推荐答案

问题是,当removeRecursive找不到数据时,它只返回最深层的递归级别的null.在递归树中上一层的调用方(也是removeRecursive)只将null赋值给current node 的左子 node 或右子 node ,并返回balance(current)(即current本身).

因此,null值不会"冒泡"回到原始调用者(remove).相反,得到null返回值的调用者只返回balance(current)返回的值,它的调用者也会这样做.一直沿着递归树向上,直到它最终返回根 node (平衡因子没有变化).

因此,当找不到数据时,remove不会得到null作为返回值.

还可能出现另一个问题,这是相反的:如果树只有一个 node ,并且删除的是that个 node ,则返回nullwill,而实际上不应该是NoSuchElementException个 node 将被抛出.

务实的解决方案是从remove中删除null支票, 在removeRecursive的基本情况下抛出NoSuchElementException,而不是返回null.

Java相关问答推荐

如何让TaskView总是添加特定的列来进行排序?

int Array Stream System. out. print方法在打印Java8时在末尾添加% sign

空手道比赛条件

将成为一个比较者.比较…在现代Java中,编译器会对`CompareTo`方法进行优化吗?

无法了解Java线程所消耗的时间

用OSQL创建索引

在添加AdMob时无法为Google Play构建应用程序包:JVM垃圾收集器崩溃和JVM内存耗尽

将JSON字符串转换为Java类

Java中不兼容的泛型类型

如何从HttpResponse实例获取Entity对象的内容?

对从Spring Boot 3.1.5升级到3.2.0的方法的查询验证失败

无法使用Java PreparedStatement在SQLite中的日期之间获取结果

具有多个模式的DateTimeForMatter的LocalDate.parse失败

如何在SWT菜单项文本中保留@字符

持续时间--为什么在秒为负数的情况下还要做额外的工作?

如何使用Java ZoneID的区域设置?

使用@ExceptionHandler的GlobalExceptionHandler还是来自服务器的REST应答的ResponseEntity?

AspectJ编织外部依赖代码,重新打包jar并强制依赖用户使用它

Spring Boot Security-每个端点都被403禁止,Spring记录一个BasicErrorController#错误(HttpServlet请求)

Java-Apache BufferedHttpEntity 在发送请求时加载整个文件