二进制搜索树,inorder方法迭代不起作用

时间:2015-12-08 07:55:48

标签: java tree binary-search-tree

我目前正在大学学习数据结构课程,我们正在学习使用链接列表的二叉搜索树。我们已经递归地检查了inOrder方法,但我想尝试迭代地执行该方法。经过一些研究,我意识到我必须使用堆栈,因为我遍历树。我能够到达树的最左侧的尽头,但是在树上移动是我遇到麻烦的地方。我已经尝试了各种版本的代码,但我最后还是以nil指针异常结束,或者它打印失序。

public void inOrder(){                
    // implement this method using non-recursive solution
   if(m_root==null){
      return;
   }
   Stack<BSTNode> myStack= new Stack<BSTNode>();
   BSTNode current=m_root;
   while (current!= null){
      myStack.push(current);
      current=current.getLeft();
   }
   while (current!=null&& !myStack.isEmpty()){
      current=myStack.peek();
      System.out.print(current.getInfo()+" ");
      myStack.pop();
      if(current.getRight()!=null){
          myStack.push(current);
      }

   }

}

2 个答案:

答案 0 :(得分:5)

从我所看到的,你的代码在第二个while循环中存在一些问题。你的想法是正确的方向,但有一些逻辑错误。你拥有的条件是正确的,但不应该在一起,它们应该是分开的。下面的代码实现了您的目标。

public void inOrder(){                
    // implement this method using non-recursive solution
   if(m_root==null){
      return;
   }
   Stack<BSTNode> myStack= new Stack<BSTNode>();
   BSTNode current=m_root;
   while (current!= null){
      myStack.push(current);
      current=current.getLeft();
   }
   while (!myStack.isEmpty()){
      current=(BSTNode)myStack.pop();
      System.out.print(current.getInfo()+" ");
      if(current.getRight() != null){
         current=current.getRight();
         while (current!= null){
            myStack.push(current);
            current=current.getLeft();
         }
      }
   }

}

答案 1 :(得分:2)

对于初学者来说,你的代码中有两个主要缺陷:你留下第一个while循环,当前指向null,因此你永远不会进入第二个while循环。而且,我想这个

if(current.getRight()!=null){
      myStack.push(current);
  }

应该使用myStack.push(current.getRight());进行更正,否则您只是试图翻转您弹出的元素并进入无限循环。但即使如此,探索的逻辑也是错误的,因为你永远不会走到从正确链接到达的节点的左侧。 我试图从你的代码开始并创建一个有效的遍历遍历:

public void inOrder(){                

   Stack<BSTNode> myStack= new Stack<BSTNode>();
   Set<BSTNode> visited = new HashSet<BSTNode>();
   BSTNode current = m_root;
   if(current!= null)
       myStack.push(current);
   while (!myStack.isEmpty()){
      current = myStack.peek();
      if(current.getLeft()!= null && !visited.contains(current.getLeft()))
          myStack.push(current.getLeft());
      else{
          //here you explore the parent node
          System.out.print(current.getInfo()+" ");
          visited.add(current);
          myStack.pop();
          //and then you see if it has children on the right
          if(current.getRight()!=null && !visited.contains(current.getRight))
              myStack.push(current.getRight());

      }
   }

}