【问题标题】:BinaryTree implementation in javajava中的二叉树实现
【发布时间】:2012-01-16 06:20:50
【问题描述】:

我有这个用于二叉树创建和遍历的代码


class Node
{
    Integer data;
    Node left;
    Node right;
    Node()
    {
        data = null;
        left = null;
        right = null;
    }
}
class BinaryTree
{
    Node head;
    Scanner input = new Scanner(System.in);
    BinaryTree()
    {
        head = null;
    }
    public void createNode(Node temp, Integer value) 
    {
        Node newnode= new Node();
        value = getData();
        newnode.data = value;
        temp = newnode;
        if(head==null)
        {
            head = temp;
        }
        System.out.println("If left child exits for ("+value+") enter y else n");
        if(input.next().charAt(0)=='y')
        {
            createNode(temp.left, value);
        }
        System.out.println("If right child exits for ("+value+") enter y else n");
        if(input.next().charAt(0)=='y')
        {
            createNode(temp.right, value);
        }       
    }
    public Integer getData()
    {
        out.println("Enter the value to insert:");
        return (Integer)input.nextInt();
    }

    public void print()
    {
        inorder(head);
    }
    public void inorder(Node node)
    {
        if(node!=null)
        {
            inorder(node.left);
            System.out.println(node.data);
            inorder(node.right);
        }
        else
            return;
    }
}

class BinaryTreeWorker
{
    static BinaryTree treeObj = null;
    static Scanner input = new Scanner(System.in);
    public static void displaymenu()
    {
        int choice;
        do{
            out.print("\n Basic operations on a tree:");
            out.print("\n 1. Create tree  \n 2. Insert \n 3. Search value \n 4. print list\n Else. Exit \n Choice:");
            choice = input.nextInt();

            switch(choice)
            {
                case 1:
                    treeObj = createBTree();
                    break;
                case 2:
                    treeObj.createNode(null, null);
                    break;
                case 3:
                    //searchnode();
                    break;
                case 4:
                    treeObj.print();
                    break;
                default:
                    return;
            }       
        }while(true);
    }
    public static BinaryTree createBTree()
    {
        return new BinaryTree();
    }
    public static void main(String[] args)
    {
        displaymenu();
    }
}

它编译并运行。但是我认为中序遍历有问题。

我创建了下面的树,

2 1 3

但它只打印 2 个。

【问题讨论】:

  • 为什么你认为它有问题?它会产生不正确的输出吗?期待什么?你实际上得到了什么?
  • 仅供参考,将用户界面(尤其是阻塞模式调用)与域对象逻辑混合是一个非常糟糕的习惯。我会考虑将逻辑分离出来;这将使调试变得更加容易。首先查看模型视图控制器 (MVC) 范例。
  • 另一种编码风格评论:inorder 不需要Node 的实例来运行,让它静态! [或者更好:让它不接受任何参数,并使用this而不是传递Node作为参数]
  • 这不是家庭作业,但我是为了自学。我已将输出添加到原始帖子中
  • 我还是想不通createNode方法有什么问题!!

标签: java algorithm binary-tree


【解决方案1】:

我已尝试以您的方式解决问题,并将解决方案粘贴在下面。虽然我没有彻底测试它,所以它可能会在某些边缘条件下失败。但我已经针对一个案例进行了测试。请让我知道它是否在某些情况下失败。我会感谢其他人帮助我更好地回答这个问题。我同意这个解决方案不是编写二叉树的最理想方法,但如果有人只是在练习,它不会受到伤害。

import java.util.Scanner;


class Node
{
    Integer data;
    Node left;
    Node right;
    Node()
    {
        data = null;
        left = null;
        right = null;
    }
}
class BinaryTree
{
    Node head;
    Scanner input = new Scanner(System.in);
    BinaryTree()
    {
        head = null;
    }

    public void createNode(Node temp,Node newnode) 
    {

        if(head==null)
        {
            System.out.println("No value exist in tree, the value just entered is set to Root");
            head = newnode;
            return;
        }
        if(temp==null)
            temp = head;

        System.out.println("where you want to insert this value, l for left of ("+temp.data+") ,r for right of ("+temp.data+")");
        char inputValue=input.next().charAt(0); 
        if(inputValue=='l'){
            if(temp.left==null)
            {
                temp.left=newnode;
                System.out.println("value got successfully added to left of ("+temp.data+")");
                return;
            }else  {
                System.out.println("value left to ("+temp.data+") is occupied 1by ("+temp.left.data+")");
                createNode(temp.left,newnode);
            }
        }
        else if(inputValue=='r')
        {
            if(temp.right==null)
            {
                temp.right=newnode;
                System.out.println("value got successfully added to right of ("+temp.data+")");
                return;

            }else  {
                System.out.println("value right to ("+temp.data+") is occupied by ("+temp.right.data+")");
                createNode(temp.right,newnode);
            }

        }else{
            System.out.println("incorrect input plz try again , correctly");
            return;
        }

    }
    public Node generateTree(){
        int [] a = new int[10];
        int index = 0; 
        while(index<a.length){
            a[index]=getData();
            index++;
        }
        if(a.length==0 ){
            return null;
        }
        Node newnode= new Node();
        /*newnode.left=null;
        newnode.right=null;*/
        return generateTreeWithArray(newnode,a,0);

    }
    public Node generateTreeWithArray(Node head,int [] a,int index){

        if(index >= a.length)
            return null;
        System.out.println("at index "+index+" value is "+a[index]);
        if(head==null)
            head= new Node();
        head.data = a[index];
        head.left=generateTreeWithArray(head.left,a,index*2+1);
        head.right=generateTreeWithArray(head.right,a,index*2+2);
        return head;
    }

    public Integer getData()
    {
        System.out.println("Enter the value to insert:");
        return (Integer)input.nextInt();
    }

    public void print()
    {
        inorder(head);
    }
    public void inorder(Node node)
    {
        if(node!=null)
        {
            inorder(node.left);
            System.out.println(node.data);
            inorder(node.right);
        }
        else
            return;
    }
}

public class BinaryTreeWorker
{
    static BinaryTree treeObj = null;
    static Scanner input = new Scanner(System.in);
    public static void displaymenu()
    {
        int choice;
        do{
            System.out.print("\n Basic operations on a tree:");
            System.out.print("\n 1. Create tree  \n 2. Insert \n 3. Search value \n 4. print list\n 5. generate a tree \n Else. Exit \n Choice:");
            choice = input.nextInt();

            switch(choice)
            {
                case 1:
                    treeObj = createBTree();
                    break;
                case 2:
                    Node newnode= new Node();
                    newnode.data = getData();
                    newnode.left=null;
                    newnode.right=null;
                    treeObj.createNode(treeObj.head,newnode);
                    break;
                case 3:
                    //searchnode();
                    break;
                case 4:
                    System.out.println("inorder traversal of list gives follows");
                    treeObj.print();
                    break;
                case 5:
                    Node tempHead = treeObj.generateTree();
                    System.out.println("inorder traversal of list with head = ("+tempHead.data+")gives follows");
                    treeObj.inorder(tempHead);
                    break;
                default:
                    return;
            }       
        }while(true);
    }
    public static Integer getData()
    {
        System.out.println("Enter the value to insert:");
        return (Integer)input.nextInt();
    }
    public static BinaryTree createBTree()
    {
        return new BinaryTree();
    }
    public static void main(String[] args)
    {
        displaymenu();
    }
}

[更新]:更新代码以使用数组生成二叉树。这将涉及更少的用户交互。

【讨论】:

    【解决方案2】:

    在Java中实现二叉树的最佳方法,所有遍历类型和测试用例如下

    package com.nitin.tree;
    
    public class Tree
    {
        private Node parent;
    
        private int  data;
    
        private int  size = 0;
    
        public Tree() {
            parent = new Node(data);
        }
    
        public void add(int data) {
    
            if (size == 0) {
                parent.data = data;
                size++;
            } else {
                add(parent, new Node(data));
            }
        }
    
        private void add(Node root, Node newNode) {
    
            if (root == null) {
                return;
            }
    
            if (newNode.data < root.data) {
    
                if (root.left == null) {
                    root.left = newNode;
                    size++;
                } else {
                    add(root.left, newNode);
                }
            } else {
    
                if (root.right == null) {
                    root.right = newNode;
                    size++;
                } else {
                    add(root.right, newNode);
                }
            }
        }
    
        public int getLow() {
    
            Node current = parent;
    
            while (current.left != null) {
                current = current.left;
            }
    
            return current.data;
        }
    
        public int getHigh() {
    
            Node current = parent;
    
            while (current.right != null) {
                current = current.right;
            }
    
            return current.data;
        }
    
        private void in(Node node) {
    
            if (node != null) {
    
                in(node.left);
                System.out.print(node.data + " ");
                in(node.right);
            }
        }
    
        private void pre(Node node) {
    
            if (node != null) {
    
                System.out.print(node.data + " ");
                pre(node.left);
                pre(node.right);
            }
        }
    
        private void post(Node node) {
    
            if (node != null) {
    
                post(node.left);
                post(node.right);
                System.out.print(node.data + " ");
            }
        }
    
        public void preorder() {
    
            System.out.print("Preorder Traversal->");
            pre(parent);
            System.out.println();
        }
    
        public void postorder() {
    
            System.out.print("Postorder Traversal->");
            post(parent);
            System.out.println();
        }
    
        public void inorder() {
    
            System.out.print("Inorder Traversal->");
            in(parent);
            System.out.println();
        }
    
        private class Node {
    
            Node left;
    
            Node right;
    
            int  data;
    
            public Node(int data) {
                this.data = data;
            }
        }
    
        public String toString() {
    
            Node current = parent;
            System.out.print("Traverse From Left ");
    
            while (current.left != null && current.right != null) {
    
                System.out.print(current.data + "->[" + current.left.data + " " + current.right.data + "] ");
                current = current.left;
            }
    
            System.out.println();
            System.out.print("Traverse From Right ");
    
            current = parent;
    
            while (current.left != null && current.right != null) {
    
                System.out.print(current.data + "->[" + current.left.data + " " + current.right.data + "] ");
                current = current.right;
            }
    
            return "";
        }
    
        public static void main(String af[]) {
    
            Tree t = new Tree();
    
            t.add(40);
            t.add(25);
            t.add(78);
            t.add(10);
            t.add(32);
            t.add(50);
            t.add(93);
            t.add(3);
            t.add(17);
            t.add(30);
            t.add(38);
    
            System.out.println(t.getLow());
    
            System.out.println(t.getHigh());
    
            System.out.println("Size-" + t.size);
    
            System.out.println(t);
    
            t.inorder();
    
            t.preorder();
    
            t.postorder();
        }
    }
    

    【讨论】:

      【解决方案3】:

      您的问题出在public void createNodes(Node temp, T data) 函数中。您传入一个与类变量 temp 同名的参数。首先,我认为您本身不需要类变量。其次,在此方法中分配给 temp 仅具有局部效果 - 您丢失了 temp 参数中的信息,但设置 temp 不会影响其在被调用方法中的值。我建议你重写该方法,使其返回指向新创建节点的指针,并将该指针分配给本地templeftright。这样,更改就会传播出去。

      【讨论】:

        【解决方案4】:

        另一种输出树:

        public void inorder() 
        {
         inorder(root);
        }
        
        protected void visit(BSTNode<T> p) 
        {
         System.out.println("Node: " + p.el + "Left Side:" + (p.left!=null?p.left.el:"null") +  
         "Right          Side:" + (p.right!=null?p.right.el:"null"));
        }
        

        【讨论】:

          【解决方案5】:

          我已将 BinaryTree 类更改如下。请特别查看 createNode 方法的更改。

          问题是,正如之前的帖子中提到的,当您的引用作为参数传递给 createNode 方法时,它不会持续存在。这种变化只是局部的。创建节点时,您需要在方法本身中返回显式节点引用。

          public Node createNode() 
          {
          
              Integer value = getData();
          
          
              Node temp = new Node(value);
              if(head==null)
              {
                  head = temp;
              }
              System.out.println("Do you want to add left branch on node("+value+")? Enter y/n");
              if(input.next().charAt(0)=='y')
              {
                  temp.left=createNode();
              }
              System.out.println("Do you want to add right branch on node("+value+")? Enter y/n");
              if(input.next().charAt(0)=='y')
              {
                  temp.right=createNode();
              }     
          
              return temp;
          }
          

          这是结果输出:

           Basic operations on a tree:
           1. Create tree  
           2. Insert 
           3. Search value 
           4. print list
           Else. Exit 
           Choice:1
          
           Basic operations on a tree:
           1. Create tree  
           2. Insert 
           3. Search value 
           4. print list
           Else. Exit 
           Choice:2
          Enter the value to insert:
          10
          Do you want to add left branch on node(10)? Enter y/n
          y
          Enter the value to insert:
          20
          Do you want to add left branch on node(20)? Enter y/n
          n
          Do you want to add right branch on node(20)? Enter y/n
          n
          Do you want to add right branch on node(10)? Enter y/n
          y
          Enter the value to insert:
          30
          Do you want to add left branch on node(30)? Enter y/n
          n
          Do you want to add right branch on node(30)? Enter y/n
          n
          
           Basic operations on a tree:
           1. Create tree  
           2. Insert 
           3. Search value 
           4. print list
           Else. Exit 
           Choice:4
          20
          10
          30
          

          我希望这对以后的某人有所帮助(即使这已经晚了 3 年......)。我自己今天才开始学习二叉树。我实际上打算以此为基础来完成更多涉及的任务!

          【讨论】:

            【解决方案6】:

            我更改了 createNode 方法以使其正常工作:

            public Node createNode(Node temp, Integer value) 
            {
                Node newnode = new Node();
                value = getData();
                newnode.data = value;
                temp = newnode;
                if(head == null)
                {
                    head = temp;
                }
                System.out.println("If left child exits for ("+value+") enter y else n");
                if(input.next().charAt(0) == 'y')
                {
                    newnode.left = createNode(newnode.left, value);
                }
                System.out.println("If right child exits for ("+value+") enter y else n");
                if(input.next().charAt(0) == 'y')
                {
                    newnode.right = createNode(newnode.right, value);
                } 
                return newnode;
            }
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2012-01-09
              • 1970-01-01
              • 2013-03-23
              • 2011-01-04
              • 2022-10-14
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多