菜单展示的递归与非递归形式实现 (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
}

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

原文地址:https://www.cnblogs.com/O-ll-O/p/14248013.html