最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

golang 實(shí)現(xiàn)菜單樹(shù)的生成方式

 更新時(shí)間:2021年04月28日 11:08:19   作者:飛渡浮舟~~  
這篇文章主要介紹了golang 實(shí)現(xiàn)菜單樹(shù)的生成方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧

golang 實(shí)現(xiàn)菜單樹(shù)的生成,包括菜單節(jié)點(diǎn)的選中狀態(tài)、半選中狀態(tài),菜單的搜索。

1 該包提供兩個(gè)方法根接口

1.1 GenerateTree(nodes, selectedNodes []INode) (trees []Tree)

GenerateTree 自定義的結(jié)構(gòu)體實(shí)現(xiàn) INode 接口后調(diào)用此方法生成樹(shù)結(jié)構(gòu)。

1.2 FindRelationNode(nodes, allNodes []INode) (respNodes []INode)

FindRelationNode 在 allTree 中查詢(xún) nodes 中節(jié)點(diǎn)的所有父子節(jié)點(diǎn) 返回 respNodes(包含 nodes , 跟其所有父子節(jié)點(diǎn))

1.3 接口 INode

// ConvertToINodeArray 其他的結(jié)構(gòu)體想要生成菜單樹(shù),直接實(shí)現(xiàn)這個(gè)接口
type INode interface {
 // GetTitle 獲取顯示名字
 GetTitle() string
 // GetId獲取id
 GetId() int
 // GetFatherId 獲取父id
 GetFatherId() int
 // GetData 獲取附加數(shù)據(jù)
 GetData() interface{}
 // IsRoot 判斷當(dāng)前節(jié)點(diǎn)是否是頂層根節(jié)點(diǎn)
 IsRoot() bool
}

2 使用

go get github.com/azhengyongqin/golang-tree-menu

2.1 定義自己的菜單結(jié)構(gòu)體并且實(shí)現(xiàn)接口 INode

// 定義我們自己的菜單對(duì)象
type SystemMenu struct {
 Id       int    `json:"id"`        //id
 FatherId int    `json:"father_id"` //上級(jí)菜單id
 Name     string `json:"name"`      //菜單名
 Route    string `json:"route"`     //頁(yè)面路徑
 Icon     string `json:"icon"`      //圖標(biāo)路徑
}
func (s SystemMenu) GetTitle() string {
 return s.Name
}
func (s SystemMenu) GetId() int {
 return s.Id
}
func (s SystemMenu) GetFatherId() int {
 return s.FatherId
}
func (s SystemMenu) GetData() interface{} {
 return s
}
func (s SystemMenu) IsRoot() bool {
 // 這里通過(guò)FatherId等于0 或者 FatherId等于自身Id表示頂層根節(jié)點(diǎn)
 return s.FatherId == 0 || s.FatherId == s.Id
}

2.2 實(shí)現(xiàn)一個(gè)將自定義結(jié)構(gòu)體SystemMenu 數(shù)組轉(zhuǎn)換成 INode 數(shù)組的方法

type SystemMenus []SystemMenu
// ConvertToINodeArray 將當(dāng)前數(shù)組轉(zhuǎn)換成父類(lèi) INode 接口 數(shù)組
func (s SystemMenus) ConvertToINodeArray() (nodes []INode) {
 for _, v := range s {
  nodes = append(nodes, v)
 }
 return
}

3 測(cè)試效果

3.1 添加測(cè)試數(shù)據(jù)

 // 模擬獲取數(shù)據(jù)庫(kù)中所有菜單,在其它所有的查詢(xún)中,也是首先將數(shù)據(jù)庫(kù)中所有數(shù)據(jù)查詢(xún)出來(lái)放到數(shù)組中,
 // 后面的遍歷遞歸,都在這個(gè) allMenu中進(jìn)行,而不是在數(shù)據(jù)庫(kù)中進(jìn)行遞歸查詢(xún),減小數(shù)據(jù)庫(kù)壓力。
 allMenu := []SystemMenu{
  {Id: 1, FatherId: 0, Name: "系統(tǒng)總覽", Route: "/systemOverview", Icon: "icon-system"},
  {Id: 2, FatherId: 0, Name: "系統(tǒng)配置", Route: "/systemConfig", Icon: "icon-config"},
  {Id: 3, FatherId: 1, Name: "資產(chǎn)", Route: "/asset", Icon: "icon-asset"},
  {Id: 4, FatherId: 1, Name: "動(dòng)環(huán)", Route: "/pe", Icon: "icon-pe"},
  {Id: 5, FatherId: 2, Name: "菜單配置", Route: "/menuConfig", Icon: "icon-menu-config"},
  {Id: 6, FatherId: 3, Name: "設(shè)備", Route: "/device", Icon: "icon-device"},
  {Id: 7, FatherId: 3, Name: "機(jī)柜", Route: "/device", Icon: "icon-device"},
 }

3.2 生成完全樹(shù)

// 生成完全樹(shù)
resp := GenerateTree(SystemMenus.ConvertToINodeArray(allMenu), nil)
bytes, _ := json.MarshalIndent(resp, "", "\t")
fmt.Println(string(bytes))
[
  {
    "title": "系統(tǒng)總覽",
    "leaf": false,
    "checked": false,
    "partial_selected": false,
    "children": [
      {
        "title": "資產(chǎn)",
        "leaf": false,
        "checked": false,
        "partial_selected": false,
        "children": [
          {
            "title": "設(shè)備",
            "leaf": true,
            "checked": false,
            "partial_selected": false,
            "children": null
          }, 
          {
            "title": "機(jī)柜",
            "leaf": true,
            "checked": false,
            "partial_selected": false,
            "children": null
          }
        ]
      }, 
      {
        "title": "動(dòng)環(huán)",
        "leaf": true,
        "checked": false,
        "partial_selected": false,
        "children": null
      }
    ]
  }, 
  {
    "title": "系統(tǒng)配置",
    "leaf": false,
    "checked": false,
    "partial_selected": false,
    "children": [
      {
        "title": "菜單配置",
        "leaf": true,
        "checked": false,
        "partial_selected": false,
        "children": null
      }
    ]
  }
]

3.3 帶選中狀態(tài)和半選中狀態(tài)的樹(shù)

// 模擬選中 '資產(chǎn)' 菜單
selectedNode := []SystemMenu{allMenu[2]}
resp = GenerateTree(SystemMenus.ConvertToINodeArray(allMenu), SystemMenus.ConvertToINodeArray(selectedNode))
bytes, _ = json.Marshal(resp)
fmt.Println(string(pretty.Color(pretty.PrettyOptions(bytes, pretty.DefaultOptions), nil)))

在這里插入圖片描述

[
  {
    "title": "系統(tǒng)總覽",
    "leaf": false,
    "checked": false,
    "partial_selected": true,
    "children": [
      {
        "title": "資產(chǎn)",
        "leaf": false,
        "checked": true,
        "partial_selected": false,
        "children": [
          {
            "title": "設(shè)備",
            "leaf": true,
            "checked": true,
            "partial_selected": false,
            "children": null
          }, 
          {
            "title": "機(jī)柜",
            "leaf": true,
            "checked": true,
            "partial_selected": false,
            "children": null
          }
        ]
      }, 
      {
        "title": "動(dòng)環(huán)",
        "leaf": true,
        "checked": false,
        "partial_selected": false,
        "children": null
      }
    ]
  }, 
  {
    "title": "系統(tǒng)配置",
    "leaf": false,
    "checked": false,
    "partial_selected": false,
    "children": [
      {
        "title": "菜單配置",
        "leaf": true,
        "checked": false,
        "partial_selected": false,
        "children": null
      }
    ]
  }
]

3.4 模擬查詢(xún)某個(gè)節(jié)點(diǎn),然后生成樹(shù)

// 模擬從數(shù)據(jù)庫(kù)中查詢(xún)出 '設(shè)備'
device := []SystemMenu{allMenu[5]}
// 查詢(xún) `設(shè)備` 的所有父節(jié)點(diǎn)
respNodes := FindRelationNode(SystemMenus.ConvertToINodeArray(device), SystemMenus.ConvertToINodeArray(allMenu))
resp = GenerateTree(respNodes, nil)
bytes, _ = json.Marshal(resp)
fmt.Println(string(pretty.Color(pretty.PrettyOptions(bytes, pretty.DefaultOptions), nil)))

在這里插入圖片描述

[
  {
    "title": "系統(tǒng)總覽",
    "leaf": false,
    "checked": false,
    "partial_selected": false,
    "children": [
      {
        "title": "資產(chǎn)",
        "leaf": false,
        "checked": false,
        "partial_selected": false,
        "children": [
          {
            "title": "設(shè)備",
            "leaf": true,
            "checked": false,
            "partial_selected": false,
            "children": null
          }
        ]
      }
    ]
  }
]

源碼地址:https://github.com/azhengyongqin/golang-tree-menu

補(bǔ)充:golang實(shí)現(xiàn)prim算法,計(jì)算最小生成樹(shù)

1、題目描述

給定一個(gè)n個(gè)點(diǎn)m條邊的無(wú)向圖,圖中可能存在重邊和自環(huán),邊權(quán)可能為負(fù)數(shù)。

求最小生成樹(shù)的樹(shù)邊權(quán)重之和,如果最小生成樹(shù)不存在則輸出impossible。

給定一張邊帶權(quán)的無(wú)向圖G=(V, E),其中V表示圖中點(diǎn)的集合,E表示圖中邊的集合,n=|V|,m=|E|。

由V中的全部n個(gè)頂點(diǎn)和E中n-1條邊構(gòu)成的無(wú)向連通子圖被稱(chēng)為G的一棵生成樹(shù),其中邊的權(quán)值之和最小的生成樹(shù)被稱(chēng)為無(wú)向圖G的最小生成樹(shù)。

輸入格式

第一行包含兩個(gè)整數(shù)n和m。

接下來(lái)m行,每行包含三個(gè)整數(shù)u,v,w,表示點(diǎn)u和點(diǎn)v之間存在一條權(quán)值為w的邊。

輸出格式

共一行,若存在最小生成樹(shù),則輸出一個(gè)整數(shù),表示最小生成樹(shù)的樹(shù)邊權(quán)重之和,如果最小生成樹(shù)不存在則輸出impossible。

2、數(shù)據(jù)

數(shù)據(jù)范圍

1≤n≤500,

1≤m≤105,

圖中涉及邊的邊權(quán)的絕對(duì)值均不超過(guò)10000。

輸入樣例:

4 5

1 2 1

1 3 2

1 4 3

2 3 2

3 4 4

輸出樣例:

6

數(shù)據(jù)圖

1、初始所有點(diǎn)的距離為正無(wú)窮,就是代碼中的0x3f3f3f3f等于1061109567

在這里插入圖片描述

2、以第一個(gè)點(diǎn)為最初點(diǎn),綠色表示選中,進(jìn)入到最小生成樹(shù)中

在這里插入圖片描述

3、以第一個(gè)更新其他與之連通的點(diǎn)的距離

在這里插入圖片描述

4、依次迭代 在這里插入圖片描述

5、最后的最小生成樹(shù)

在這里插入圖片描述

3、樸素prim算法步驟時(shí)間復(fù)雜度O(n^2)

1、先初始化所有點(diǎn)距離為正無(wú)窮

2、迭代n次,依次用到集合的最小點(diǎn)更新剩余點(diǎn)距離

3、將已經(jīng)確定的點(diǎn)加入到st集合中,st數(shù)組為一個(gè)bool類(lèi)型

4、代碼實(shí)現(xiàn)

/*
該圖是稠密圖,使用鄰接矩陣
*/
package main
import (
   "bufio"
   "fmt"
   "os"
   "strconv"
   "strings"
)
const (
   N   = 510
   INF = 0x3f3f3f3f
)
var (
   n, m int
   dist [N]int
   g    [N][N]int
   st   [N]bool
)
func readLine(r *bufio.Reader) []int {
   s, _ := r.ReadString('\n')
   ss := strings.Fields(s)
   res := make([]int, len(ss))
   for i, v := range ss {
      res[i], _ = strconv.Atoi(v)
   }
   return res
}
func prim() int {
   // 初始化距離集合 dist
   for i := 0; i < N; i++ {
      dist[i] = 0x3f3f3f3f
   }
   // 迭代n次
   res := 0 //res 存儲(chǔ)最小生成樹(shù)的大小即邊的長(zhǎng)度總和
   for i := 0; i < n; i++ {
      // 找到集合外距離最短的點(diǎn)
      t := -1
      for j := 1; j <= n; j++ {
         if !st[j] && (t == -1 || dist[t] > dist[j]) {
            t = j
         }
      }
      // 迭代結(jié)束,此時(shí)的t就是距離最小點(diǎn)
      // 情況一:圖上的點(diǎn)不連通,不能組成最小生成樹(shù)
      if i > 0 && dist[t] == INF {
         return INF
      } // 如果不是第一個(gè)點(diǎn)并且最小店的距離是正無(wú)窮,則表示圖是不連通的
      if i > 0 {
         res += dist[t]
      } // 如果不是第一個(gè)點(diǎn),這個(gè)t就表示當(dāng)前點(diǎn)到集合某一個(gè)點(diǎn)的最小距離
      // 用最小距離點(diǎn)更新其他跟 "現(xiàn)階段形成的生成樹(shù)" 的最短距離,
      //注意更新的順序,自環(huán)是不應(yīng)該被加到最小生成樹(shù),所以,為了避免自環(huán)加入最小生成樹(shù),提前更新res
      for j := 1; j <= n; j++ {
         dist[j] = min(dist[j], g[t][j]) // 此步驟注意是dijkstra的區(qū)別,
      }
      st[t] = true
   }
   return res
}
func min(a, b int) int {
   if a >= b {
      return b
   } else {
      return a
   }
}
func main() {
   r := bufio.NewReader(os.Stdin)
   input := readLine(r)
   n, m = input[0], input[1]
   //fmt.Scanf("%d%d\n", &n, &m)
   // 初始化距離
   for i := 0; i < N; i++ {
      for j := 0; j < N; j++ {
         if i == j {
            g[i][j] = 0
         } else {
            g[i][j] = 0x3f3f3f3f
         }
      }
   }
   //
   for m > 0 {
      m--
      in := readLine(r)
      a, b, c := in[0], in[1], in[2] //輸入
      g[a][b] = min(g[a][b], c)
      g[b][a] = g[a][b] // 無(wú)向圖
   }
   t := prim()
   if t == INF {
      fmt.Println("impossible")
   } else {
      fmt.Println(t)
   }
}

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教。

相關(guān)文章

  • go語(yǔ)言實(shí)現(xiàn)簡(jiǎn)易比特幣系統(tǒng)錢(qián)包的原理解析

    go語(yǔ)言實(shí)現(xiàn)簡(jiǎn)易比特幣系統(tǒng)錢(qián)包的原理解析

    這篇文章主要介紹了go語(yǔ)言實(shí)現(xiàn)簡(jiǎn)易比特幣系統(tǒng)錢(qián)包的原理解析,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-04-04
  • Golang?Template實(shí)現(xiàn)自定義函數(shù)的操作指南

    Golang?Template實(shí)現(xiàn)自定義函數(shù)的操作指南

    這篇文章主要為大家詳細(xì)介紹了Golang如何利用Template實(shí)現(xiàn)自定義函數(shù)的操作,文中的示例代碼簡(jiǎn)潔易懂,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2025-02-02
  • GO使用socket和channel實(shí)現(xiàn)簡(jiǎn)單控制臺(tái)聊天室

    GO使用socket和channel實(shí)現(xiàn)簡(jiǎn)單控制臺(tái)聊天室

    今天小編給大家分享一個(gè)簡(jiǎn)單的聊天室功能,聊天室主要功能是用戶(hù)可以加入離開(kāi)聊天室,實(shí)現(xiàn)思路也很簡(jiǎn)單明了,下面小編給大家?guī)?lái)了完整代碼,感興趣的朋友跟隨小編一起看看吧
    2021-12-12
  • Golang設(shè)計(jì)模式之組合模式講解

    Golang設(shè)計(jì)模式之組合模式講解

    這篇文章主要介紹了Golang設(shè)計(jì)模式之組合模式,組合模式針對(duì)于特定場(chǎng)景,如文件管理、組織管理等,使用該模式能簡(jiǎn)化管理,使代碼變得非常簡(jiǎn)潔
    2023-01-01
  • Golang學(xué)習(xí)之map的用法詳解

    Golang學(xué)習(xí)之map的用法詳解

    在Golang(又稱(chēng)Go語(yǔ)言)中,map是一種非常有用的數(shù)據(jù)結(jié)構(gòu),所以這篇文章小編就來(lái)帶大家一起深入了解一下map的用法,感興趣的小伙伴可以了解一下
    2023-06-06
  • gin自定義中間件解決requestBody不可重復(fù)讀問(wèn)題(最新推薦)

    gin自定義中間件解決requestBody不可重復(fù)讀問(wèn)題(最新推薦)

    這篇文章主要介紹了gin自定義中間件解決requestBody不可重復(fù)讀問(wèn)題,本文通過(guò)示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-04-04
  • Golang跳轉(zhuǎn)語(yǔ)句continue與goto使用語(yǔ)法詳解

    Golang跳轉(zhuǎn)語(yǔ)句continue與goto使用語(yǔ)法詳解

    這篇文章主要介紹了Golang跳轉(zhuǎn)語(yǔ)句continue與goto使用語(yǔ)法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧
    2023-01-01
  • 一文帶你了解Golang中reflect反射的常見(jiàn)錯(cuò)誤

    一文帶你了解Golang中reflect反射的常見(jiàn)錯(cuò)誤

    go?反射的錯(cuò)誤大多數(shù)都來(lái)自于調(diào)用了一個(gè)不適合當(dāng)前類(lèi)型的方法,?而且,這些錯(cuò)誤通常是在運(yùn)行時(shí)才會(huì)暴露出來(lái),而不是在編譯時(shí),如果我們傳遞的類(lèi)型在反射代碼中沒(méi)有被覆蓋到那么很容易就會(huì)?panic。本文就介紹一下使用?go?反射時(shí)很大概率會(huì)出現(xiàn)的錯(cuò)誤,需要的可以參考一下
    2023-01-01
  • Go中調(diào)用JS代碼(otto)的實(shí)現(xiàn)示例

    Go中調(diào)用JS代碼(otto)的實(shí)現(xiàn)示例

    Otto是一個(gè)用Go語(yǔ)言實(shí)現(xiàn)的JavaScript解釋器,可用于執(zhí)行和操作JavaScript代碼,適合在Go項(xiàng)目中執(zhí)行簡(jiǎn)單的JS腳本,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2024-10-10
  • Go 實(shí)現(xiàn)熱重啟的詳細(xì)介紹

    Go 實(shí)現(xiàn)熱重啟的詳細(xì)介紹

    這篇文章主要介紹了Go 實(shí)現(xiàn)熱重啟的詳細(xì)介紹,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-09-09

最新評(píng)論

丰顺县| 石棉县| 沙河市| 株洲县| 永登县| 高台县| 东乡| 崇礼县| 香港 | 三亚市| 淄博市| 高要市| 栾川县| 荔波县| 斗六市| 广汉市| 诸暨市| 察哈| 柳江县| 镇康县| 库尔勒市| 探索| 安化县| 绥宁县| 柯坪县| 濮阳市| 夏邑县| 永和县| 康定县| 石景山区| 封丘县| 汉寿县| 麻栗坡县| 文安县| 平塘县| 乌恰县| 连南| 霍州市| 太湖县| 聂拉木县| 龙岩市|