Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/397.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 面向对象设计,设计一棵树_Java_Oop_Tree - Fatal编程技术网

Java 面向对象设计,设计一棵树

Java 面向对象设计,设计一棵树,java,oop,tree,Java,Oop,Tree,我正在用Java创建一个(非典型)树,它将由三个类组成:节点、分支和叶 每个节点将连接到的分支存储在哈希集中。分支应该指向一个派生节点或一个叶,但我不知道如何编写代码。我是否会在分支类中有两个单独的变量,一个节点和一个叶,以及两组getter和setter,即使我永远不会同时使用它们?在这方面是否有最佳做法 我在想,也许可以将node和leaf子类创建为同一个超类,但它们在代码方面完全没有共同之处(即不同的变量类型、函数等) 编辑: 节点引用分支和 每个分支引用一个节点或叶使用基本信息创建叶类

我正在用Java创建一个(非典型)树,它将由三个类组成:节点、分支和叶

每个节点将连接到的分支存储在哈希集中。分支应该指向一个派生节点或一个叶,但我不知道如何编写代码。我是否会在分支类中有两个单独的变量,一个节点和一个叶,以及两组getter和setter,即使我永远不会同时使用它们?在这方面是否有最佳做法

我在想,也许可以将node和leaf子类创建为同一个超类,但它们在代码方面完全没有共同之处(即不同的变量类型、函数等)

编辑: 节点引用分支和
每个分支引用一个节点或叶

使用基本信息创建叶类

创建包含对叶的引用的分支类

创建包含对Brahces的引用的Node类

然后尝试查找递归以及如何使用它来构造这样的结构:)

这是我的计划。虽然不是很优雅,但它完成了任务

下面是Leaf类:

public class Leaf {
    private String text;

    public Leaf(String text) {
        this.text = text;
    }

    public String getText() {
        return text;
    }

    public void setString(String newString) {
        text = newString;
    }

    @Override
    public String toString() {
        return text;
    }
}
下面是分支类:

public class Branch<T> {
    private String text;
    private HashSet<T> list;

    public Branch(String text) {
        this.text = text;
        list = new HashSet<>();
    }

    public String getText() {
        return text;
    }

    public void setText(String newText) {
        text = newText;
    }

    public HashSet<T> getHashSet() {
        return list;
    }

    public void setHashSet(HashSet<T> newList) {
        list = newList;
    }

    public String getAllLeaves() {
        StringBuilder sb = new StringBuilder();
        sb.append(text).append("\n");
        for(T t : list) {
            sb.append("\t\t");
            sb.append(t.toString()).append("\n");
        }
        return sb.toString();
    }

    @Override
    public String toString() {
        return text;
    }
}

希望这有帮助

我可能会这样说:

  interface BranchDestination {
    boolean isLeaf();
  }

  class Node implements BranchDestination {
    private Set branches;
    public boolean isLeaf() {
      return false;
    }
    ...
  }

  class Leaf implements BranchDestination {
    public boolean isLeaf() {
      return true;
    }
    ...
  }

  class Branch {
    BranchDestination destination;
    ...
  }

我非常喜欢为叶/节点类定义一个
接口
,并在每个类中实现该接口。我将在该接口中定义一个简单的函数(下面的语法可能是错误的,但它是PSEDOO ish代码):

接口分支{
公共对象[]GetVals();
}
公营部门
{
公共部门项目;
}
公共类叶实现BranchItem
{
私有对象myVal=;
公共对象[]GetVals(){
返回新对象[]{myVal};
}
}
公共类节点实现BranchItem
{
私人MyBranchs[]=;
公共对象[]GetVals(){
对象[]myArray=新对象[];
foreach(我的分支中的分支b)
{
myArray.addTo(b.item.GetVals());
}
返回myArray;
}
}
遍历节点时,只需在分支上迭代并调用
GetVals()

Leaf
类将简单地返回它的存储值

节点
类将递归地在其分支上循环,对每个分支调用
GetVals()
,并将其添加到自己返回的数组中


这只是一个简单的实现。如果您想要排序顺序、处理冲突或重复数据,或任何类似的性质,它可能会变得更复杂。

您能详细说明一下吗?我知道我将使用递归来使用节点和分支构建树的主要部分,但在树的底部会有叶子,它们的用途与主要节点不同。你必须用图形或文本来表示它吗?@Vipar:嗯,声明此类类型确实涉及类型递归,但这个术语通常在程序员的词汇表中找不到(不过,请再次参阅沃思的“算法+数据”)。然而,使用这种构造肯定需要递归函数。分支类通常会引用节点,然后只在末尾引用叶子。最简单的方法是使每个节点同时包含一组对子节点的引用和一个数据引用(即
节点
)。如果在叶节点之外不能拥有数据,请在运行时强制执行该规则。除了数据类之外,您只需要一个类,
节点
。分支有其用途。我理解基本的方法,这就是为什么我说这是非典型的。
public class TreeConstruct {
    public static void main(String[] args) {
        Leaf l1 = new Leaf("Leaf 1");
        Leaf l2 = new Leaf("Leaf 2");
        Leaf l3 = new Leaf("Leaf 3");
        Leaf l4 = new Leaf("Leaf 4");

        Branch<Leaf> b1 = new Branch("Branch 1");
        Branch<Leaf> b2 = new Branch("Branch 2");

        Node<Branch> n1 = new Node("Node 1");

        b1.getHashSet().add(l1);
        b1.getHashSet().add(l2);
        b1.getHashSet().add(l3);
        b2.getHashSet().add(l4);

        n1.getHashSet().add(b1);
        n1.getHashSet().add(b2);

        System.out.println(printNodeTree(n1));
    }

    public static String printNodeTree(Node<Branch> n) {
            StringBuilder sb = new StringBuilder();
            sb.append(n.getText()).append("\n");
            for(Branch b : n.getHashSet()) {
                sb.append("\t");
                sb.append(b.getAllLeaves());
            }
            return sb.toString();
        }
}
Node 1
        Branch 1
                Leaf 1
                Leaf 3
                Leaf 2
        Branch 2
                Leaf 4
  interface BranchDestination {
    boolean isLeaf();
  }

  class Node implements BranchDestination {
    private Set branches;
    public boolean isLeaf() {
      return false;
    }
    ...
  }

  class Leaf implements BranchDestination {
    public boolean isLeaf() {
      return true;
    }
    ...
  }

  class Branch {
    BranchDestination destination;
    ...
  }
interface BranchItem {
    public object[] GetVals();
}

public class Branch
{
   public BranchItem item;
}

public class Leaf implements BranchItem
{
    private object myVal = <your data here>;

    public object[] GetVals() {
      return new object[] { myVal };
    }
}

public class Node implements BranchItem
{
    private myBranches[] = <List of Branches>;

    public object[] GetVals() {

      object[] myArray = new object[];
      foreach (BranchItem b in myBranches)
      {
         myArray.addTo(b.item.GetVals());
      }

      return myArray;
    }
}