项目作者: Kwanil

项目描述 :
Tree Data Structure, JAVA8
高级语言: Java
项目地址: git://github.com/Kwanil/tree-data-structure.git
创建时间: 2018-02-04T03:04:26Z
项目社区:https://github.com/Kwanil/tree-data-structure

开源协议:

下载


Tree

-jdk8

-no dependency

Java로 일반적인 계층적 구조인 Tree 자료구조를 작성하였다.

  • Java8의 stream을 통한 TreeNode의 접근등을 할수있도록 하였다.
  • TreeNode.stream에서 검색 방식은 3가지로 너비우선, 깊이우선, 부모방향이다.
  • 트리노드로 구성되지 않은 List구조를 TreeNode로 간편하게 변경하는 Collector를 제공한다.
    (TreeNode<Category> root = categories.stream().collect(toTreeNode());)
  • 트리노드객체로 구성하지 않더라도, Pojo객체 내부에 mutable한 children setter가 있다면, 객체자체를 Tree로 구성할수 있다
    (Category root = categories.stream().collect(toTree());)

Adjacency list Model 구조를 TreeNode로 간편 변경가능하도록한다.

  1. @Getter
  2. class Category {
  3. private int parentKey;
  4. private int key;
  5. private String name;
  6. public Category(int parentKey, int key, String name) {
  7. this.parentKey = parentKey;
  8. this.key = key;
  9. this.name = name;
  10. }
  11. }
  12. // DB List
  13. public List<Category> selectCategories(){
  14. return Arrays.asList(
  15. new Category(0, 1, "root"),
  16. new Category(3, 6, "sub2-1"),
  17. new Category(2, 4, "sub1-1"),
  18. new Category(2, 5, "sub1-2"),
  19. new Category(1, 2, "sub1"),
  20. new Category(1, 3, "sub2"),
  21. new Category(1, 7, "sub3")
  22. );
  23. }
  24. List<Category> categories = selectCategories();
  25. TreeNode<Category> root = categories.stream().collect(toTreeNode());
  26. public Collector<Category,?,TreeNode<Category>> toTreeNode() {
  27. return TreeNodeCollector<Category,Integer>.treeNode()
  28. .id(Category::getId) //ID는??
  29. .parentId(Category::getParentId) //Parent ID
  30. .root(i->i.parentId==0) //Root는??
  31. .toTree();
  32. }
  33. <결과>
  34. > root
  35. >> sub1
  36. >>> sub1-1
  37. >>> sub1-2
  38. >> sub2
  39. >>> sub2-1
  40. >> sub3
  41. assertThat(treeNode.get().getName(), is("root"));
  42. assertThat(treeNode.getChildAt(0).getName(), is("sub1"));
  43. assertThat(treeNode.getChildAt(1).getName(), is("sub2"));
  44. assertThat(treeNode.getChildAt(2).getName(), is("sub3"));
  45. assertThat(treeNode.getSubTreeAt(0).getChildAt(0).getName(), is("sub1-1"));
  46. assertThat(treeNode.getSubTreeAt(0).getChildAt(1).getName(), is("sub1-2"));
  47. assertThat(treeNode.getSubTreeAt(1).getChildAt(0).getName(), is("sub2-1"));

TreeNode를 탐색하는 Utility제공

  • 어떠한 TreeNode 한 지점(A)을 탐색하는 로직 제공.
  • 탐색알고리즘은 깊이우선탐색(TreeSearchOption.depthFirst()), 너비우선탐색(TreeSearchOption.breadthFirst()) 제공한다. 또한 현재 노드에서 부모방향(TreeSearchOption.toParent())으로 탐색할수 있다
  • 단일 노드탐색 Trees.searchFirst(root, A지점)
  • 다중 노드탐색 Trees.searchAll(root, 찾고자하는 predicate)
  1. /**
  2. * TreeNode Template
  3. *
  4. * root
  5. * sub1
  6. * sub1-1
  7. * sub1-1-1
  8. * sub1-1-2
  9. * sub1-2
  10. * sub1-2-1
  11. * sub1-3
  12. * sub2
  13. * sub2-1
  14. * sub2-2
  15. * sub2-2-1
  16. * sub2-2-2
  17. * sub3
  18. */
  19. TreeNode<String> node = Trees.searchFirst(treeNode, "sub1-1");
  20. assertEquals(node.get(), "sub1-1");
  21. List<TreeNode<String>> sub1s = Trees.searchAll(treeNode, o->o.get().startsWith("sub1-1"));
  22. assertEquals(3, sub1s.size());
  23. //sub1-1, sub1-1-1, sub1-1-2
  • 어느 한지점(A)의 노드를 가지고있을때, root에서부터 경로를 얻어올수 있다. Trees.pathFromRoot(A지점)
  • 어느 한지점(A)에서 root 노드를 찾아갈수 있다. Trees.root(A지점)
  • 어느 한지점(A)에서 모든 자식노드(leaves)를 얻어올수있다, Tree.leaves(A지점)
  1. @Test
  2. public void pathFromRoot() throws Exception {
  3. TreeNode<String> node = Trees.searchFirst(treeNode, "sub1-1-2");
  4. List<TreeNode<String>> parents = Trees.pathFromRoot(node);
  5. List<String> parentContents = Trees.contents(parents);
  6. assertEquals("root", parentContents.get(0));
  7. assertEquals("sub1", parentContents.get(1));
  8. assertEquals("sub1-1", parentContents.get(2));
  9. assertEquals("sub1-1-2", parentContents.get(3));
  10. }
  11. @Test
  12. public void root() throws Exception {
  13. TreeNode<String> node = Trees.searchFirst(treeNode, "sub1-1-2");
  14. TreeNode<String> root = Trees.root(node);
  15. assertEquals(root, treeNode);
  16. }
  17. @Test
  18. public void leaves() throws Exception {
  19. List<TreeNode<String>> leaves = Trees.leaves(treeNode);
  20. List<String> contents = Trees.contents(leaves);
  21. assertTrue(contents.contains("sub1-1-1"));
  22. assertTrue(contents.contains("sub1-1-2"));
  23. assertTrue(contents.contains("sub1-2-1"));
  24. assertTrue(contents.contains("sub1-3"));
  25. assertTrue(contents.contains("sub2-1"));
  26. assertTrue(contents.contains("sub2-2-1"));
  27. assertTrue(contents.contains("sub2-2-2"));
  28. assertTrue(contents.contains("sub3"));
  29. }