首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >面向对象设计,设计树

面向对象设计,设计树
EN

Stack Overflow用户
提问于 2013-05-24 02:47:18
回答 3查看 1.7K关注 0票数 1

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

每个节点将其连接到的分支存储在HashSet中。分支应该指向后代节点或叶,但我不确定如何编码。我会不会只有两个独立的变量,一个Node和一个Leaf在分支类中,以及两组getter和setter,尽管我永远不会用到这两个?在这方面有没有最佳实践?

我在想,也许可以让节点和叶子类成为同一个超类,但它们在代码方面完全没有共同点(即不同的变量类型、函数等)。

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

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-05-24 03:05:00

我可能会这样说:

代码语言:javascript
运行
复制
  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;
    ...
  }
票数 1
EN

Stack Overflow用户

发布于 2013-05-24 02:50:23

使用基本信息创建Leaf类。

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

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

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

这就是我要做的。虽然不是很优雅,但它完成了工作。

下面是Leaf类:

代码语言:javascript
运行
复制
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;
    }
}

下面是Branch类:

代码语言:javascript
运行
复制
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类:

代码语言:javascript
运行
复制
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;
    }
}

一个小的测试程序来尝试它:

代码语言:javascript
运行
复制
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();
        }
}

输出将为:

代码语言:javascript
运行
复制
Node 1
        Branch 1
                Leaf 1
                Leaf 3
                Leaf 2
        Branch 2
                Leaf 4

希望这能有所帮助!

票数 1
EN

Stack Overflow用户

发布于 2013-05-24 03:08:55

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

代码语言:javascript
运行
复制
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()并将其添加到自己返回的数组中。

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

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16721624

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档