`

用栈(stack)实现树形菜单

    博客分类:
  • java
 
阅读更多

1.具有排序的菜单:

/**
 * 树形菜单:兄弟结点是有序的,同级目录按Menu的position升序排列
 *
 * @author Administrator
 *
 */
public class StackOrderTree {

 private Map<Long, Menu> menuMap = InitBean.getMenuMap();
 private static MenuComparator<Menu> mc = new MenuComparator<Menu>();

 private Node<Menu> createMenuTree(Set<Long> sonMenus) {
  Map<String, Node<Menu>> allMenuMap = new HashMap<String, Node<Menu>>();
  Node<Menu> root = new Node<Menu>(null);
  Node<Menu> parent = null;
  Node<Menu> node = null;

  for (Long e : sonMenus) {
   Menu menu = menuMap.get(e);
   Stack<Menu> stack = new Stack<Menu>();
   while (menu != null) {
    stack.push(menu);
    if (menu.getParent() == null) {
     menu = null;
    } else {
     menu = menuMap.get(menu.getParent().getId());
    }
   }

   parent = root;
   while (!stack.isEmpty()) {
    Menu md = stack.pop();
    if (parent.containsTheChild(md)) {
     node = parent.getTheChild(md);
    } else {
     node = new Node<Menu>(md, parent, mc); //同级目录排序
     allMenuMap.put(md.getMemo(), node);
    }
    parent = node;
   }
  }
  return root;
 }

 public void setMenuMap(Map<Long, Menu> menuMap) {
  this.menuMap = menuMap;
 }

 private String showTree() {//菜单权限
  Set<Long> sonMenus = new HashSet<Long>();//假设拥有权限的菜单
  // sonMenus.add(100L); //只需要带url的就能把不带url的父结点显示出来
  sonMenus.add(113L);
  sonMenus.add(101L);
  sonMenus.add(102L);
  sonMenus.add(104L);

  sonMenus.add(120L); // 三级目录
  sonMenus.add(122L); // 四级目录

  Node<Menu> root = createMenuTree(sonMenus);
  StringBuilder sb = new StringBuilder();

  for (int i = 0; i < root.getChildren().size(); i++) {
   Node<Menu> node = root.getChildren().get(i);
   String selectStr = "";
   sb.append("<h3 " + selectStr
     + "><span><img src='/images/a.jpg' alt='"
     + node.getData().getMenuName() + "' /></span>"
     + node.getData().getMenuName() + "</h3>\n");

   sb.append("<div class='list_menu'>");
   List list = node.getChildren();
   for (Node<Menu> son : node.getChildren()) {
    createMenuHtml(sb, son);
   }
   sb.append("</div>\n");
  }
  return sb.toString();
 }

 private void createMenuHtml(StringBuilder sb, Node<Menu> root) {
  Menu dto = (Menu) root.getData();
  if (dto.getMenuUrl().equals("")) {// 表示目录
   sb.append("<div class='list_menu'>");
   sb.append("<h1>" + dto.getMenuName() + "</h1>\n");
  } else {
   sb.append("<div class='shortcut_sub'><a target='mainframe' href='"
     + dto.getMenuUrl() + "'>" + dto.getMenuName()
     + "</a></div>\n");
  }

  for (Node<Menu> node : root.getChildren()) {
   createMenuHtml(sb, node);
   if (node.isLast())
    sb.append("</div>");
  }
 }

 public static void main(String args[]) {
  StackOrderTree st = new StackOrderTree();
  String s = st.showTree();
  System.out.println(s);
 }
}

2.树形结点:

public class Node<T> {

 private T data;
 private Node<T> parent;
 private List<Node<T>> children=new ArrayList<Node<T>>();
 
 public Node(T data){
  this.data=data;
 }
 
 public Node(T data,Node<T> parent){
  this.data=data;
  this.parent=parent;
  
  parent.addChild(this);
 }
 
  public void addChild(Node<T> node) {
         if(node != null) {
             node.parent = this;
             children.add(node); 
         }
     }
 
  public Node(T data, Node<T> parent, Comparator<T> comparator) {
         this.data = data;
         this.parent = parent;

         parent.addChild(this, comparator);
     }   

     public void addChild(Node<T> node, Comparator<T> comparator) {
      if(node != null) {
             node.parent = this;
            
             boolean insert = false;
             for(int i = 0; i < children.size(); i++) {
              if(comparator.compare(node.getData(), children.get(i).getData()) == -1) {
               children.add(i, node);
               insert = true;
               break;
              }
             }
            
             if(!insert) {
              children.add(node);
             }
         }
     }
 
 public boolean containsTheChild(T data) {
     return getTheChild(data) != null;
    }
 
  public Node<T> getTheChild(T data) {
      Node<T> child = null;
      if(hasChild()) {
       for(Node<T> node : children) {
        if(data.equals(node.getData())) {
         child = node;
         break;
        }
       }
      }
      
      return child;
   }
  public boolean isLeaf() {
         return children == null || children.isEmpty();
     }

  public boolean hasChild() {
         return !isLeaf();
  }
 
  public boolean isLast() {
         if(parent == null) {
             return true; //root node
         } else {
             if(parent.getChildren() == null || parent.getChildren().isEmpty()) {
                 throw new IllegalArgumentException("错误的树结构");
             }
            
             int index = parent.getChildren().indexOf(this);//indexof 返回列表中首次出现指定元素的索引,也就是第一级子目录
             if(index == -1) {
                 throw new IllegalArgumentException("错误的树结构");
             } else {
                 return index == (parent.getChildren().size() - 1);
             }
         }
 }
 
 public T getData() {
  return data;
 }
 public void setData(T data) {
  this.data = data;
 }
 public Node<T> getParent() {
  return parent;
 }
 public void setParent(Node<T> parent) {
  this.parent = parent;
 }
 public List<Node<T>> getChildren() {
  return children;
 }
 
}

3.比较器:

public class MenuComparator<T extends Menu> implements Comparator<T> {

 public int compare(Menu m, Menu e) {

  return m.getPosition().compareTo(e.getPosition());// 升序
 }

}

4.菜单:

public class Menu {

 private Long id;

 private String menuName;

 private String memo;

 private Menu parent;

 private String menuUrl;

 private Long position;

 public Menu(Long id, String menuName, String memo, Long position,
   Menu parent, String menuUrl) {
  this.id = id;
  this.menuName = menuName;
  this.memo = memo;
  this.position = position;
  this.parent = parent;
  this.menuUrl = menuUrl;
 }

 public String getMenuName() {
  return menuName;
 }

 public void setMenuName(String menuName) {
  this.menuName = menuName;
 }

 public String getMemo() {
  return memo;
 }

 public void setMemo(String memo) {
  this.memo = memo;
 }

 public Menu getParent() {
  return parent;
 }

 public void setParent(Menu parent) {
  this.parent = parent;
 }

 public Long getId() {
  return id;
 }

 public void setId(Long id) {
  this.id = id;
 }

 public void setMenuUrl(String menuUrl) {
  this.menuUrl = menuUrl;
 }

 public String getMenuUrl() {
  return menuUrl;
 }

 public void setPosition(Long position) {
  this.position = position;
 }

 public Long getPosition() {
  return position;
 }
}

分享到:
评论

相关推荐

    struts+hibernate树形菜单

    当我们需要在Web应用中实现树形菜单时,通常会结合这两个框架来完成。 树形菜单是一种常见的用户界面元素,它以层级结构展示数据,例如网站导航、文件系统或者组织架构。在Web应用中,用户可以通过点击展开或折叠...

    java-Press-out-the-stack-.zip_out

    在这个场景下,我们探讨的是如何利用栈的特性来构建树形结构,特别是针对Oracle数据库查询结果进行处理,例如构建菜单树对象。Oracle数据库是关系型数据库管理系统之一,广泛应用于大型企业级应用中,而JDBC(Java ...

    java动态树

    在这个项目中,我们看到一个使用Struts框架构建的动态树结构,它与MySQL数据库相结合,实现了动态加载数据到树形展示的功能。 Struts是Apache软件基金会的一个开源项目,它是一个用于构建企业级Web应用的MVC(Model...

    资源管理器用TreeView和ListView实现

    TreeView是Windows Forms或WPF应用程序中常用的一种控件,它可以以树形结构展示数据,非常适合用来表示文件系统的目录层次。在资源管理器中,每个节点代表一个文件夹,展开节点则可以显示其包含的子文件夹和文件。要...

    数据结构习题(二叉树子系统)

    二叉树是一种特殊的树形数据结构,每个节点最多有两个子节点,通常分为左子节点和右子节点。 二叉树的主要操作包括插入、删除、查找以及遍历。在`MAIN.C`文件中,很可能包含了这些操作的实现。在C语言中,我们通常...

    PHP无限级分类-非递归

    非递归方法通常使用栈(stack)或队列(queue)数据结构来实现。这里我们使用栈,步骤如下: 1. 初始化一个空栈。 2. 将所有顶级分类(`parent_id`为0的分类)压入栈中。 3. 当栈不为空时,循环执行以下操作: - ...

    数据结构与算法分析:php语言描述

    我们将会从数组、链表到更复杂的树形结构以及堆和散列表等进行逐一解析,并通过实际代码示例来帮助读者更好地掌握这些核心概念。 #### 数组(Array) **概述** - 数组是一种最基本也是最常用的数据结构之一。它是一...

    四月全国计算机等级考试二级ACCESS笔试试题及答案知识.pdf

    9. E-R图:在E-R图中,实体用矩形表示,属性用椭圆形表示,联系用菱形表示。 10. 数据库相关概念:DB(Database)是数据的集合,DBS(Database System)是包括DB和相关软件的系统,DBMS(Database Management ...

    cc:取自coco2d的数据结构,用于前端开发

    6. **堆(Heap)**:一种树形数据结构,常用于优先级队列,提供快速的查找最大或最小元素的能力。在游戏开发中,堆可能用于实现优先级渲染或AI决策。 7. **图(Graph)**:表示对象之间的关系,常用于路径寻找、游戏...

    2021-2022计算机二级等级考试试题及答案No.19496.docx

    - **解释**: 示例代码中分别定义了`Stack`类和`Queue`类来实现栈和队列的功能。栈是一种后进先出(LIFO)的数据结构,队列则是一种先进先出(FIFO)的数据结构。通过定义相应的插入和删除操作,这些类可以有效地模拟...

    2021-2022计算机二级等级考试试题及答案No.14349.docx

    层次数据模型是最古老的数据模型之一,它使用树形结构来表示实体及其之间的关系。在该模型中,每个实体都有一个父节点(除了根节点外),并且可以有任意数量的子节点。 ### 8. C 语言标识符大小写敏感性 C 语言中的...

    2021-2022计算机二级等级考试试题及答案No.12149.docx

    - **详细解释**:层次模型以树形结构表示数据间的层次关系;关系模型采用二维表格的形式表示数据及其之间的联系;网状模型则允许多个节点之间存在多对多的关系。这些模型各有特点,适用于不同的应用场景。 ### 7. ...

Global site tag (gtag.js) - Google Analytics