JAVA算法 List实体创建多叉树,使用递归遍历 实现多级菜单管理

项目描述

最近使用SSM做后台系统,已经使用递归的形式动态获取到多级菜单,现写一个多级菜单的管理程序,用于直接遍历出所有菜单,并实现创建菜单以及对菜单的管理与删除。

具体实现效果如下

实现方案

在后台以深度先序递归的方式将数据以JSON的形式遍历出来,在菜单数据表中,主要使用了两个,一个是id,一个是pid,其他数据字段再此不描述。具体流程图

1、先创建多叉树主节点主节点的pid=null,id=0。2、通过查找下一节点节点pid=主节点id值,进行创建子节点

3、遍历使用深度优先遍历的先序搜索进行遍历输出

实现代码

多叉树的节点结构为一个实体MenuTree.class

package com.song.model;


import java.util.ArrayList;
import java.util.List;

import com.alibaba.fastjson.JSON;
import com.song.model.AdminMenu;

public class  MenuTree{
//AdminMenu 为菜单实体
	private AdminMenu nodeEntity;
	private MenuTree parentNode;
	private List<MenuTree> childNodes;  

	public MenuTree(AdminMenu nodeEntity) { 
		this.getParentNode();  
        initChildList();  
	}
	
	
	public MenuTree () {
		initChildList();
	}

    /* 插入一个child节点到当前节点中 */  
	public void addChildNode(MenuTree childNode){
		initChildList();
        this.childNodes.add(childNode);
    }
	
	    
	public MenuTree getParentNode() {
        return parentNode;
    }
 
    public void setParentNode(MenuTree parentNode) {
        this.parentNode = parentNode;
    }
 
    public AdminMenu getNodeEntity() {
        return nodeEntity;
    }
 
    public void setNodeEntity(AdminMenu nodeEntity) {
        this.nodeEntity = nodeEntity;
    }
 
    public List<MenuTree> getChildNodes() {
        return childNodes;
    }
 
    public void setChildNodes(List<MenuTree> childNodes) {
        this.childNodes = childNodes;
    }


}
//返回前端JSON数组
	@ResponseBody
	@RequestMapping(value="/menupower",produces = "application/json;charset=UTF-8")
	public String menupower() {
		List<AdminMenu> menuall = adminmenuservice.superapimenuall();
		List<AdminMenu> menuallapi =new ArrayList<AdminMenu>();
		//创建一个AdminMenu的对象作为多叉树的根的值
		AdminMenu root=new AdminMenu();
		root.setId(0);
		//创建跟节点
		MenuTree roottree =new MenuTree();
		roottree.setNodeEntity(root);
		//开始创建多叉树
		CreateTree(roottree,menuall);
		//遍历多叉树,roottree 为多叉树的根节点,这个函数将根节点遍历给全局变量allmenu对象数组中
		DFStraverse(roottree,menuallapi);
		if(menuallapi.size()==0) {
			return SuperCommon.SuperJson(menuallapi,"超级权限中的菜单管理出错!");
		}
		return JSON.toJSONString(menuallapi);
	}
//创建多叉树
public boolean CreateTree(MenuTree menutree,List<AdminMenu> menuall) {
		if(menutree==null)
			return false;
		//先获取同等级节点
		List<AdminMenu> rootMenu = new ArrayList<AdminMenu>();
		for (AdminMenu res : menuall) {
			if (menutree.getNodeEntity().getId().equals(res.getPid())) {// 父节点是0的,为根节点。
				rootMenu.add(res);
			}
		}
		// 根据Menu类的order排序 ,对同等级节点进行排序
		Collections.sort(rootMenu, order());
		//对rootmenu继续创建节点
		for(AdminMenu res :rootMenu) {
			System.out.println("menutree.getNodeEntity().getId()---------"+menutree.getNodeEntity().getId()+"--------res.getPid()------"+res.getPid());
			if(menutree.getNodeEntity().getId().equals(res.getPid())) {
				System.out.println(JSON.toJSONString(res));
                //使用正则表达式判断获取的id属于第几级菜单,赋予不通的cname值
                if(Pattern.matches("^[1-9]{1}00",Integer.toString(res.getId()))) {
                	res.setCname("&nbsp;"+res.getName());
                }else if(Pattern.matches("^[1-9]{2}0$",Integer.toString(res.getId()))) {
                	res.setCname("&nbsp;&nbsp;&nbsp; ├"+res.getName());
                }else {
                	res.setCname("&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |└"+res.getName());
                }
				MenuTree leaf=new MenuTree();
				leaf.setNodeEntity(res);				
				menutree.addChildNode(leaf);
				CreateTree(leaf,menuall);	
			}
		}
		return true;		
	}
/* 遍历一棵树,层次遍历 */ 
	
   
    public void DFStraverse(MenuTree tree,List<AdminMenu> menuapi) {  
        if (tree.getChildNodes() == null || tree.getChildNodes().isEmpty())  
            return;
        int childNumber = tree.getChildNodes().size();  
        for (int i = 0; i < childNumber; i++) {  
        	MenuTree child = tree.getChildNodes().get(i);
        	menuapi.add(child.getNodeEntity());
        	DFStraverse(child,menuapi);  
        }  
    }    
    
    /*
	 * 排序,根据order排序
	 */
	public Comparator<AdminMenu> order() {
		Comparator<AdminMenu> comparator = new Comparator<AdminMenu>() {
			@Override
			public int compare(AdminMenu o1, AdminMenu o2) {
				if (o1.getSort() != o2.getSort()) {
					return o1.getSort() - o2.getSort();
				}
				return 0;
			}
		};
		return comparator;
	}
					

返回前端的数据格式

总结

在采用多叉树遍历所有菜单时,有点笨,使用了两天时间,到现在才明白过来具体具体算法思路,再创建多叉树的时候时由于遇到的一些问题,比如以后创建菜单时会不会发生id冲突,或者创建菜单的级别不同等问题,在创建菜单数据表时对菜单的id与pid做了以下情况,同时菜单只能建立三级,同级只能有九列。

 

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值