欧美阿v视频在线大全_亚洲欧美中文日韩V在线观看_www性欧美日韩欧美91_亚洲欧美日韩久久精品

主頁 > 知識庫 > golang 實現菜單樹的生成方式

golang 實現菜單樹的生成方式

熱門標簽:涿州代理外呼系統 壽光微信地圖標注 阿克蘇地圖標注 電話機器人軟件免費 百度地圖標注后傳給手機 評價高的400電話辦理 excel地圖標注分布數據 外呼系統顯本地手機號 外呼系統用什么卡

golang 實現菜單樹的生成,包括菜單節點的選中狀態、半選中狀態,菜單的搜索。

1 該包提供兩個方法根接口

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

GenerateTree 自定義的結構體實現 INode 接口后調用此方法生成樹結構。

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

FindRelationNode 在 allTree 中查詢 nodes 中節點的所有父子節點 返回 respNodes(包含 nodes , 跟其所有父子節點)

1.3 接口 INode

// ConvertToINodeArray 其他的結構體想要生成菜單樹,直接實現這個接口
type INode interface {
 // GetTitle 獲取顯示名字
 GetTitle() string
 // GetId獲取id
 GetId() int
 // GetFatherId 獲取父id
 GetFatherId() int
 // GetData 獲取附加數據
 GetData() interface{}
 // IsRoot 判斷當前節點是否是頂層根節點
 IsRoot() bool
}

2 使用

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

2.1 定義自己的菜單結構體并且實現接口 INode

// 定義我們自己的菜單對象
type SystemMenu struct {
 Id       int    `json:"id"`        //id
 FatherId int    `json:"father_id"` //上級菜單id
 Name     string `json:"name"`      //菜單名
 Route    string `json:"route"`     //頁面路徑
 Icon     string `json:"icon"`      //圖標路徑
}
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 {
 // 這里通過FatherId等于0 或者 FatherId等于自身Id表示頂層根節點
 return s.FatherId == 0 || s.FatherId == s.Id
}

2.2 實現一個將自定義結構體SystemMenu 數組轉換成 INode 數組的方法

type SystemMenus []SystemMenu
// ConvertToINodeArray 將當前數組轉換成父類 INode 接口 數組
func (s SystemMenus) ConvertToINodeArray() (nodes []INode) {
 for _, v := range s {
  nodes = append(nodes, v)
 }
 return
}

3 測試效果

3.1 添加測試數據

 // 模擬獲取數據庫中所有菜單,在其它所有的查詢中,也是首先將數據庫中所有數據查詢出來放到數組中,
 // 后面的遍歷遞歸,都在這個 allMenu中進行,而不是在數據庫中進行遞歸查詢,減小數據庫壓力。
 allMenu := []SystemMenu{
  {Id: 1, FatherId: 0, Name: "系統總覽", Route: "/systemOverview", Icon: "icon-system"},
  {Id: 2, FatherId: 0, Name: "系統配置", Route: "/systemConfig", Icon: "icon-config"},
  {Id: 3, FatherId: 1, Name: "資產", Route: "/asset", Icon: "icon-asset"},
  {Id: 4, FatherId: 1, Name: "動環", Route: "/pe", Icon: "icon-pe"},
  {Id: 5, FatherId: 2, Name: "菜單配置", Route: "/menuConfig", Icon: "icon-menu-config"},
  {Id: 6, FatherId: 3, Name: "設備", Route: "/device", Icon: "icon-device"},
  {Id: 7, FatherId: 3, Name: "機柜", Route: "/device", Icon: "icon-device"},
 }

3.2 生成完全樹

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

3.3 帶選中狀態和半選中狀態的樹

// 模擬選中 '資產' 菜單
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": "系統總覽",
    "leaf": false,
    "checked": false,
    "partial_selected": true,
    "children": [
      {
        "title": "資產",
        "leaf": false,
        "checked": true,
        "partial_selected": false,
        "children": [
          {
            "title": "設備",
            "leaf": true,
            "checked": true,
            "partial_selected": false,
            "children": null
          }, 
          {
            "title": "機柜",
            "leaf": true,
            "checked": true,
            "partial_selected": false,
            "children": null
          }
        ]
      }, 
      {
        "title": "動環",
        "leaf": true,
        "checked": false,
        "partial_selected": false,
        "children": null
      }
    ]
  }, 
  {
    "title": "系統配置",
    "leaf": false,
    "checked": false,
    "partial_selected": false,
    "children": [
      {
        "title": "菜單配置",
        "leaf": true,
        "checked": false,
        "partial_selected": false,
        "children": null
      }
    ]
  }
]

3.4 模擬查詢某個節點,然后生成樹

// 模擬從數據庫中查詢出 '設備'
device := []SystemMenu{allMenu[5]}
// 查詢 `設備` 的所有父節點
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": "系統總覽",
    "leaf": false,
    "checked": false,
    "partial_selected": false,
    "children": [
      {
        "title": "資產",
        "leaf": false,
        "checked": false,
        "partial_selected": false,
        "children": [
          {
            "title": "設備",
            "leaf": true,
            "checked": false,
            "partial_selected": false,
            "children": null
          }
        ]
      }
    ]
  }
]

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

補充:golang實現prim算法,計算最小生成樹

1、題目描述

給定一個n個點m條邊的無向圖,圖中可能存在重邊和自環,邊權可能為負數。

求最小生成樹的樹邊權重之和,如果最小生成樹不存在則輸出impossible。

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

由V中的全部n個頂點和E中n-1條邊構成的無向連通子圖被稱為G的一棵生成樹,其中邊的權值之和最小的生成樹被稱為無向圖G的最小生成樹。

輸入格式

第一行包含兩個整數n和m。

接下來m行,每行包含三個整數u,v,w,表示點u和點v之間存在一條權值為w的邊。

輸出格式

共一行,若存在最小生成樹,則輸出一個整數,表示最小生成樹的樹邊權重之和,如果最小生成樹不存在則輸出impossible。

2、數據

數據范圍

1≤n≤500,

1≤m≤105,

圖中涉及邊的邊權的絕對值均不超過10000。

輸入樣例:

4 5

1 2 1

1 3 2

1 4 3

2 3 2

3 4 4

輸出樣例:

6

數據圖

1、初始所有點的距離為正無窮,就是代碼中的0x3f3f3f3f等于1061109567

2、以第一個點為最初點,綠色表示選中,進入到最小生成樹中

3、以第一個更新其他與之連通的點的距離

4、依次迭代

5、最后的最小生成樹

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

1、先初始化所有點距離為正無窮

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

3、將已經確定的點加入到st集合中,st數組為一個bool類型

4、代碼實現

/*
該圖是稠密圖,使用鄰接矩陣
*/
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 存儲最小生成樹的大小即邊的長度總和
   for i := 0; i  n; i++ {
      // 找到集合外距離最短的點
      t := -1
      for j := 1; j = n; j++ {
         if !st[j]  (t == -1 || dist[t] > dist[j]) {
            t = j
         }
      }
      // 迭代結束,此時的t就是距離最小點
      // 情況一:圖上的點不連通,不能組成最小生成樹
      if i > 0  dist[t] == INF {
         return INF
      } // 如果不是第一個點并且最小店的距離是正無窮,則表示圖是不連通的
      if i > 0 {
         res += dist[t]
      } // 如果不是第一個點,這個t就表示當前點到集合某一個點的最小距離
      // 用最小距離點更新其他跟 "現階段形成的生成樹" 的最短距離,
      //注意更新的順序,自環是不應該被加到最小生成樹,所以,為了避免自環加入最小生成樹,提前更新res
      for j := 1; j = n; j++ {
         dist[j] = min(dist[j], g[t][j]) // 此步驟注意是dijkstra的區別,
      }
      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] // 無向圖
   }
   t := prim()
   if t == INF {
      fmt.Println("impossible")
   } else {
      fmt.Println(t)
   }
}

以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。如有錯誤或未考慮完全的地方,望不吝賜教。

您可能感興趣的文章:
  • golang通過遞歸遍歷生成樹狀結構的操作
  • goland 恢復已更改文件的操作
  • goland 清除所有的默認設置操作
  • Golang 的defer執行規則說明
  • golang 的string與[]byte轉換方式

標簽:汕頭 雞西 銅川 重慶 欽州 吐魯番 蘭州 梅河口

巨人網絡通訊聲明:本文標題《golang 實現菜單樹的生成方式》,本文關鍵詞  golang,實現,菜單,樹,的,生成,;如發現本文內容存在版權問題,煩請提供相關信息告之我們,我們將及時溝通與處理。本站內容系統采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《golang 實現菜單樹的生成方式》相關的同類信息!
  • 本頁收集關于golang 實現菜單樹的生成方式的相關信息資訊供網民參考!
  • 推薦文章
    欧美阿v视频在线大全_亚洲欧美中文日韩V在线观看_www性欧美日韩欧美91_亚洲欧美日韩久久精品
  • <rt id="w000q"><acronym id="w000q"></acronym></rt>
  • <abbr id="w000q"></abbr>
    <rt id="w000q"></rt>
    亚洲一区自拍偷拍| 婷婷一区二区三区| 亚洲电影一区二区| 91丨porny丨国产入口| 亚洲欧美小视频| 国产精品国产精品国产专区不蜜 | 国产v综合v亚洲欧| 国产精品无码一区二区三区免费 | 久久国产福利国产秒拍| 麻豆国产精品一区二区三区| 亚洲精品乱码久久久久久蜜桃图片| 在线观看免费成人| 欧美v国产在线一区二区三区| 国产精品免费人成网站| 日本网站在线观看一区二区三区 | 专区另类欧美日韩| 丁香五精品蜜臀久久久久99网站 | 日韩西西人体444www| 精品捆绑美女sm三区| 午夜在线电影亚洲一区| 粉嫩久久99精品久久久久久夜| 亚洲一二三四五六区| 91精品国产综合久久久蜜臀图片| 亚洲 欧美综合在线网络| 日本一区二区在线观看视频| 男女全黄做爰文章| 日韩色在线观看| 亚洲女人的天堂| 国产成人精品免费一区二区| 欧美人禽zoz0强交| 久久久久久久久久久久久夜| 午夜精品爽啪视频| 极品粉嫩小仙女高潮喷水久久 | 国产精品夫妻自拍| 麻豆精品国产91久久久久久| 中文字幕免费在线看线人动作大片| 久久无码av三级| 久久av中文字幕片| 精品亚洲乱码一区二区| 久久综合色综合88| www.久久精品| 欧美乱熟臀69xxxxxx| 一区二区视频在线| 一区二区三区四区在线播放 | 国产又粗又长又黄的视频| 欧美激情自拍偷拍| 99国产精品久久久久久久久久| av黄色在线免费观看| 国产午夜亚洲精品理论片色戒 | 国产黄色成人av| 日本少妇xxxxx| 国产精品久久久久久久裸模| 中文字幕乱码在线人视频| 日韩欧美一卡二卡| 成人亚洲一区二区一| 欧美精三区欧美精三区| 亚洲6080在线| www.xx日本| 亚洲成av人片观看| 美女福利视频网| 中文字幕精品在线不卡| 亚洲熟女乱综合一区二区| 精品福利在线导航| 91日韩精品一区| 欧美日韩一区久久| 亚洲在线免费播放| 无码少妇一区二区| 欧美国产禁国产网站cc| 国产成人精品网址| 91精品国产一区二区三区| 久久看人人爽人人| chinese麻豆新拍video| 久久一区二区视频| 先锋资源在线视频| 欧美日韩一级大片网址| 亚洲3atv精品一区二区三区| 日本猛少妇色xxxxx免费网站| 亚洲黄色av一区| 欧美亚洲色综久久精品国产| 一区二区三区不卡视频| 中文字幕在线国产| 欧美一区二区三区男人的天堂| 国产精品影视网| 欧美一区二区大片| 91小视频免费观看| 51精品秘密在线观看| 国产成人aaaa| 欧美电影免费提供在线观看| 91麻豆国产香蕉久久精品| 国产视频一区在线播放| 在线免费观看污视频| 亚洲免费观看高清在线观看| 久久午夜精品视频| 日本91福利区| 欧美欧美欧美欧美首页| 麻豆一区二区三区| 永久免费看片直接| 精品一区二区三区的国产在线播放| 99久久精品久久亚洲精品| 秋霞午夜鲁丝一区二区老狼| 午夜欧美一区二区三区在线播放| 久久久久麻豆v国产| 一个色综合av| 99久久久久久久久久| 国产区在线观看成人精品| 玖草视频在线观看| 亚洲国产高清在线| 亚洲三级在线视频| 日韩美女啊v在线免费观看| 2019男人天堂| 久久精品二区亚洲w码| 欧美一区二区三区色| 国产伦理在线观看| 久久久不卡影院| 国产美女免费无遮挡| 自拍偷自拍亚洲精品播放| 久久精品日韩无码| 首页国产欧美久久| 777久久久精品| av av在线| 国产精品网曝门| 欧美日韩国产一二三区| 国产一区中文字幕| 欧美日本精品一区二区三区| av影片在线播放| 亚洲永久精品国产| 久久噜噜色综合一区二区| 国产一区二区不卡老阿姨| 欧美日本一区二区三区四区| 久久无码专区国产精品s| 亚洲国产视频a| 在线综合亚洲欧美在线视频| 99久久婷婷国产| 亚洲欧美日韩成人高清在线一区| 法国空姐电影在线观看| 激情图片小说一区| 国产欧美精品区一区二区三区| 污片免费在线观看| 日本不卡一二三区黄网| 欧美日韩中文字幕一区| 精品人妻二区中文字幕| 午夜精品久久久久影视| 91成人看片片| 国产精品456| 精品美女被调教视频大全网站| 亚洲综合网在线观看| 亚洲第一电影网| 色拍拍在线精品视频8848| 日韩久久久久久久久久久| 国产精品高潮久久久久无| 在线亚洲一区观看| 一边摸一边做爽的视频17国产| 免费成人深夜小野草| 欧美肥妇毛茸茸| 草草影院第一页| 国产一区二区三区香蕉| 国产精品国产三级国产aⅴ原创| 欧美在线免费观看亚洲| 不卡av在线网| 亚洲国产精品人人做人人爽| 欧美大肚乱孕交hd孕妇| 亚洲天堂网一区二区| 国产一区二区三区黄视频 | 在线观看一区二区三区视频| 婷婷亚洲久悠悠色悠在线播放| 精品久久久久久久久久久久久久久久久 | 一区在线观看免费| 欧美区在线观看| 91麻豆制片厂| 国产一区二区三区免费看| 精品国产一区二区三区四区四| 老司机免费视频| 国产一区二区三区四区在线观看| 1区2区3区国产精品| 欧美一区国产二区| 26uuu成人网| 亚洲成a人片在线观看中文| 欧美大片拔萝卜| 一本久久a久久精品亚洲 | 亚洲欧美在线视频| 黑鬼狂亚洲人videos| 国产精品一区二区在线免费观看| 激情小说亚洲一区| 亚洲国产日韩精品| 国产视频一区在线观看| 五月天色婷婷丁香| 亚洲精品激情视频| 国产成人亚洲综合a∨婷婷| 亚洲国产成人精品视频| 国产欧美一区二区精品仙草咪| 欧美日韩国产一级| 国产乱子轮xxx农村| 国产伦精品一区三区精东| 日韩黄色免费网站| 亚洲色图自拍偷拍美腿丝袜制服诱惑麻豆| 亚洲欧美一区二区三区四区五区| 自拍视频一区二区| 91视频国产观看| 丝袜美腿成人在线| 精品国产乱码久久久久久久|