面向对象设计,设计树

时间:2013-05-23 18:47:18

标签: java oop tree

我在Java中创建一个(非典型的)树,它将由三个类组成:node,branch和leaf

每个节点在HashSet中存储它所连接的分支。分支应该导致后代节点或叶子,但我不知道如何编码。我是否只有两个独立的变量,分支类中的一个Node和一个Leaf,以及两组getter和setter,即使我永远不会同时使用它们?这方面有最佳做法吗?

我在考虑制作相同超类的节点和叶子类,但它们在代码方面完全没有共同点(即不同的变量类型,函数等)。

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

3 个答案:

答案 0 :(得分:1)

使用基本信息制作Leaf类。

创建包含对Leafs的引用的Branch类。

创建包含Brahces引用的Node类。

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

这是我的理由。虽然不是很优雅,但它可以完成工作。

这是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;
    }
}

最后是Node类:

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

    public Node(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 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

希望这有帮助!

答案 1 :(得分:1)

我可能会选择这样的东西:

  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;
    ...
  }

答案 2 :(得分:1)

我喜欢为叶子/节点类定义interface的想法,并在每个类中实现该接口。我会在该接口中定义一个简单的函数(下面的语法可能不对,但它是pseduo-ish代码):

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;
    }
}

遍历您的节点时,只需遍历分支并调用GetVals()

Leaf类只会返回它的存储值。

Node类将递归循环遍历它的分支,在每个分支上调用GetVals()并将其添加到它自己的返回数组中。

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