zoukankan      html  css  js  c++  java
  • 菜单展示的递归与非递归形式实现 (go语言版)

    1.递归形式实现

    节点分为三种:根节点、中间节点、叶子节点,其中一个树可以有多个根节点
    结构体

    
    type MenuTree struct {
    	Name 			string                  `json:"name"`
    	ID   			string                  `json:"id"`     
    	Description             string                  `json:"description"`
    	ParentID   		string                  `json:"parentId"`
    	HeaderGroupID           string                  `json:"headerGroupId"`//用于记录该节点所属的根节点,可以便于查找指定根节点的所有child
    	Children               []*MenuTree 		`json:"childrens"`
    }
    

    获取指定节点的叶子节点

    func GetNodeLeafIds(menuTree *MenuTree, nodeID string) []string {
    	node := findNode(menuTree, nodeID)
    	if node == nil {
    		return nil
    	}
    	ids := make([]string, 0)
    	getLeafIds(node, &ids)
    	return ids
    }
    

    查找某一中间节点是否有包含指定节点

    func findNode(menuTree *MenuTree, nodeID string) *MenuTree {
    	if menuTree.ID == nodeID {
    		return menuTree
    	}
    	for _, child := range menuTree.Children {
    		if child.ID == nodeID {
    			return child
    		}
    		findNode(child, nodeID)
    	}
    	return nil
    }
    

    获取指定节点的所有叶子节点

    func getLeafIds(node *MenuTree, lefts *[]string) {
    	for _, child := range node.Children {
    		if child.Children == nil || len(child.Children) == 0 {
    			*lefts = append(*lefts, child.ID)
    		}
    		getLeafIds(child, lefts)
    	}
    }
    

    获取所有根节点

    func getRoots(datas []*MenuTree) []*MenuTree {
    	roots := []*MenuTree{}
    	for _, data := range datas {
    		if data.ParentID == "" {//父节点为空的为根节点
    			root := MenuTree{
    			        Name         :		data.Name,              
    				ID           :   	data.ID,	                  
    				Description  :    	data.Description,                 
    				ParentID     :   	data.ParentID,	                  
    				HeaderGroupID:  	data.HeaderGroupID,               
    				Children     :      []*MenuTree{},
    			}
    			roots = append(roots, &root)
    		}
    	}
    	return roots
    }
    

    给指定的根节点构建树,datas为所有菜单的数据,root为指定根节点

    func buildChild(datas []*MenuTree, root *MenuTree) *MenuTree {
    	for _, data := range datas {
    		if data.ParentGroupID == node.DeviceGroupID {
    			node.Children = append(node.Children, buildChild(datas, data))
    		}
    	}
    	return node
    }
    

    构建所有根节点的树

    func BuildTree(allMenus []*MenuTree) []*MenuTree {
    	roots := getRoots(allMenus)
    	for _, root := range roots {
    		buildChild(allMenus, root)
    	}
    	return roots
    }
    

    2.非递归形式实现

    func buildMenuTree(allMenus []*MenuTree ) map[string]*MenuTree {
    
    	temp := map[string]*MenuTree{}
    
    	result := map[string]*MenuTree{}
    	for _, menu := range allMenus {
    		temp[menu.ID] = &menu
    	}
    
    	for _, node := range temp {
    		if temp[node.ParentID] == nil {
    			result[node.ID] = node
    		} else {
    			temp[node.ParentID].Children = append(temp[node.ParentID].Children, node)
    		}
    	}
    
    	return result
    }
    

    如果觉得写得不好,欢迎指出;如果觉得写得不错,欢迎大佬赞赏。
    对卡卡的赞赏

  • 相关阅读:
    vue 自定义全局按键修饰符
    Vue 过滤器
    v-if、v-show 指令
    其他内置函数
    python中序列化和反序列化
    jmeter图形化html报告核心指标介绍
    jmeter在linux系统下如何进行压力测试
    文件操作的其他方法
    文件处理操作
    内置函数reduce()
  • 原文地址:https://www.cnblogs.com/O-ll-O/p/14248013.html
Copyright © 2011-2022 走看看