class BinaryTree{
class Node{ // 声明一个节点类
private Comparable data ; // 保存具体的内容
private Node left ; // 保存左子树
private Node right ; // 保存右子树
public Node(Comparable data){
this.data = data ;
}
public void addNode(Node newNode){
// 确定是放在左子树还是右子树
if(newNode.data.compareTo(this.data)<0){ // 内容小,放在左子树
if(this.left==null){
this.left = newNode ; // 直接将新的节点设置成左子树
}else{
this.left.addNode(newNode) ; // 继续向下判断
}
}
if(newNode.data.compareTo(this.data)>=0){ // 放在右子树
if(this.right==null){
this.right = newNode ; // 没有右子树则将此节点设置成右子树
}else{
this.right.addNode(newNode) ; // 继续向下判断
}
}
}
public void printNode(){ // 输出的时候采用中序遍历
if(this.left!=null){
this.left.printNode() ; // 输出左子树
}
System.out.print(this.data + "\t") ;
if(this.right!=null){
this.right.printNode() ;
}
}
};
private Node root ; // 根元素
public void add(Comparable data){ // 加入元素
Node newNode = new Node(data) ; // 定义新的节点
if(root==null){ // 没有根节点
root = newNode ; // 第一个元素作为根节点
}else{
root.addNode(newNode) ; // 确定是放在左子树还是放在右子树
}
}
public void print(){
this.root.printNode() ; // 通过根节点输出
}
};
public class ComparableDemo03{
public static void main(String args[]){
BinaryTree bt = new BinaryTree() ;
bt.add(8) ;
bt.add(3) ;
bt.add(3) ;
bt.add(10) ;
bt.add(9) ;
bt.add(1) ;
bt.add(5) ;
bt.add(5) ;
System.out.println("排序之后的结果:") ;
bt.print() ;
}
};
不理解的是下面这个方法
public void printNode(){
if(this.left!=null){  
this.left.printNode() ; //如果左子树为空。那么就继续向下递归直到最后一
左子树为空才打印下面那句话。
}
//也就是直到左子树为空了 。下面的代码才会被执行 ,
System.out.print(this.data + "\t") ;    //这句话能正常打印。
if(this.right!=null){                   //如果该节点的右子树也为空,那么这个方法不就终止了嚒? 最终只打印了一句话。
this.right.printNode() ;
}
}
打印结果为:1 3 3 5 5 8 9 10
可是结果并不是我想的那样。 打印结果将添加到里面的元素全部升序打印出来了。这里很是不理解,求指点。

解决方案 »

  1.   

    你的问题不是会不会二叉树的问题是会不会递归的问题
    左边叶子执行了printNode输出后没有右边的结点就返回了,但是叶子的父节点方法还没执行完撒
      

  2.   

    我知道你的理解问题出在那里解释一下:
    public void printNode() { // 输出的时候采用中序遍历
    System.out.print(this.data + "\t");
                 if (this.left != null) {
    this.left.printNode(); // 输出左子树
    }
    if (this.right != null) {
    this.right.printNode();
    }

    }
    如果打印语句,加在第一行,那就是每个Node,先打印根,再打字左孩子,再打印右孩子排序之后的结果:
    1 5 5 3 3 9 10 8
    如果像楼主这样:if (this.left != null) {
    this.left.printNode(); // 输出左子树
    }
    System.out.print(this.data + "\t");
    if (this.right != null) {
    this.right.printNode();
    }
    先打印左,再打印根,再打印右边。。为什么打字结果是:排序之后的结果:
    1 3 3 5 5 8 9 10
    请看着我给你画的那棵二叉树。
    相信,前面二个数1和3,你都没有问题。问题在于为什么先打3,而不是5你试想想遍历到右边的3的时候,先遍历左边。。发现没有左孩子,那么就执行了那个打印语句,把3打印出来了,再才遍历右节点。。
    public void printNode() { // 输出的时候采用中序遍历
    if (this.left != null) {
    this.left.printNode(); // 输出左子树
    }
    if (this.right != null) {
    this.right.printNode();
    }
    System.out.print(this.data + "\t");
    }
    打印语句放最后。。则是先打左,再打印右边,再后才打印根节点
    请楼主对着我给你画的二叉树,分别用这三种打印方法,去理解相信你能明白
      

  3.   

    中序遍历就是
    对每一个节点,先看左节点,再看自己,再看右节点
    抽象成方法就是
    class Node
    {
      private Node left;
      private Node right;
      public midOrder()
      {
        if(left!=null)
        {left.midOrder();}//先左
        System.out.println(this.toString());//然后自己
        if(right!=null)
        {right.midOrder();}//最后右
      }
    }
      

  4.   


    嗯 ,明白了许多 。刚刚不明白 ,是我以为if (this.left != null) {
                this.left.printNode(); // 我开始以为如果左子树不为空,则一直递归。直到左子树为空。然后打印下面那句话 。
            }
            System.out.print(this.data + "\t");
    //执行打印语句以后,执行下面的代码  
            if (this.right != null) {
                this.right.printNode();
            }
    //我开始以为,这样执行一遍以后就结束了。(以为只会打印一个值) 但是刚刚断点调试了看了下 ,发现该节点的父节点还没有执行完。又执行父节点。然后继续递归知道打印完。