Java二进制树/访客模式

时间:2015-10-29 04:59:00

标签: java oop design-patterns binary-tree

所以我真的能得到这个我想知道是否有人可以帮助我,这个程序的目的是使用访问者模式从给定二叉树中的人的名称生成字符串列表,如果不是真的确定如何使用append函数来执行此操作。我如何将这个人与其父母一起追加?

import tester.Tester;

//Representation for an ancestor tree
interface IAT {
    <R> R accept(IATVisitor<R> visitor);

    //Append two lists
    IList<String> append(IList<String> l);
}
//-------------------------------------------------------------------------------------------------
//Unknown person
class Unknown implements IAT {
    Unknown() {
    }
    public <R> R accept(IATVisitor<R> visitor) {
        return visitor.visitUnknown(this);
    }
    //append two an unknown
    public IList<String> append(IList<String> l) {
        return l;
    }

}    
//-------------------------------------------------------------------------------------------------
//Representation for a person
class Person implements IAT {
    String name;
    int yob;
    boolean isMale;
    IAT mom;
    IAT dad;
    //Constructor
    Person(String name, int yob, boolean isMale, IAT mom, IAT dad) {
        this.name = name;
        this.yob = yob;
        this.isMale = isMale;
        this.mom = mom;
        this.dad = dad;
    }
    public <R> R accept(IATVisitor<R> visitor) {
        return visitor.visitPerson(this);
    }
    //append parent and children of tree
    public IList<String> append(IList<String> l) {
        //
    }

}
//-------------------------------------------------------------------------------------------------
interface IATVisitor<R> {
    R visitUnknown(Unknown u);
    R visitPerson(Person p);
}
//-------------------------------------------------------------------------------------------------
//IAT Visitor that returns a list of the names of all people
class IATVisitGetNames implements IATVisitor<IList<String>> {
    public IList<String> visitUnknown(Unknown u) {
        return new MT<String>();
    }
    public IList<String> visitPerson(Person p) {
        return new Cons<String>(p.name, new MT<String>());
    }
}

//Examples
class ExamplesIATV {
    //persons
    Unknown a = new Unknown();
    Person ralph = new Person("Ralph", 1995, true, a, a);
    Person kevin = new Person("Kevin", 1994, true, a , a);
    Person julia = new Person("Julia", 1991, false, ralph, a);
    Person lily = new Person("Lily", 1990, false, kevin, julia);
    Person who = new Person("?", 1738, false, lily, a);

    //Visitor
    IATVisitor<IList<String>> byName = new IATVisitGetNames(); 


    //test Vistior
    boolean testGetNames(Tester t) {
        return 
                t.checkExpect(who.accept(byName), new MT<String>());
    }
}

1 个答案:

答案 0 :(得分:1)

首先 - 您想从树中收集所有名称。您需要遍历功能,例如:

public void traverse(Node root) {
   //do somesing with node
   System.out.println(root.value);
   if (root.left != null) {
      traverse(root.left);
   }
   if (root.right != null) {
      traverse(root.right);
   }
}

第二 - 您想使用访客模式。维基百科怎么说:

  

访客 - 是一种将算法与对象结构分离的方法   它运作的地方。

因此访问者不适合travers / itereate逻辑。有了访问者,我们只能在节点上填充一些逻辑:

public void traverseWithVisitor(Node root, IVisitor v) {
  root.accept(v);
  if (root.left != null) {
     traverseWithVisitor(root.left, v);
  }
  if (root.right != null) {
     traverseWithVisitor(root.right, v);
  }
}

现在将我们的收集名称逻辑封装在访问者中:

class AggregateNamesVisitor implements IVisitor {

   public List<Integer> names = new ArrayList<>();

   @Override
   public void visit(Node node) {
      names.add(node.value);
   }
}

我们可以像这样使用它:

AggregateNamesVisitor aggregateVisitor = new AggregateNamesVisitor();
traverseWithVisitor(root, aggregateVisitor);
aggregateVisitor.names.forEach(name -> System.out.print(" " + name));