golang通過遞歸遍歷生成樹狀結(jié)構(gòu)的操作
業(yè)務(wù)場景:
一個機(jī)構(gòu)查詢科室信息的時候,希望返回樹狀結(jié)構(gòu)的嵌套格式;
解決辦法:
通過遞歸和指針,嵌套成對應(yīng)的結(jié)構(gòu)體;
借鑒了前人的代碼,但是最后遞歸的指針調(diào)用自己也是調(diào)試了半天才出來,這里獻(xiàn)上完整的示例代碼.
package main
import (
"fmt"
"encoding/json"
)
type dept struct {
DeptId string `json:"deptId"`
FrameDeptStr string `json:"frameDeptStr"`
Child []*dept `json:"child"`
}
func main() {
depts := make([]dept,0)
var a dept
a.DeptId = "1"
a.FrameDeptStr = ""
depts = append(depts,a)
a.DeptId="3"
a.FrameDeptStr = "1"
depts = append(depts,a)
a.DeptId="4"
a.FrameDeptStr = "1"
depts = append(depts,a)
a.DeptId="5"
a.FrameDeptStr = "13"
depts = append(depts,a)
a.DeptId="6"
a.FrameDeptStr = "13"
depts = append(depts,a)
fmt.Println(depts)
deptRoots := make([]dept,0)
for _,v := range depts{
if v.FrameDeptStr == ""{
deptRoots= append(deptRoots,v)
}
}
pdepts := make([]*dept,0)
for i,_ := range depts{
var a *dept
a = &depts[i]
pdepts = append(pdepts,a)
}
//獲取了根上的科室
fmt.Println("根上的科室有:",deptRoots)
var node *dept
node = &depts[0]
makeTree(pdepts,node)
fmt.Println("the result we got is",pdepts)
data, _ := json.Marshal(node)
fmt.Printf("%s", data)
}
func has(v1 dept,vs []*dept) bool {
var has bool
has = false
for _,v2 := range vs {
v3 := *v2
if v1.FrameDeptStr+v1.DeptId == v3.FrameDeptStr{
has = true
break
}
}
return has
}
func makeTree(vs []*dept,node *dept) {
fmt.Println("the node value in maketree is:",*node)
childs := findChild(node,vs)
fmt.Println(" the child we got is :",childs)
for _,child := range childs{
fmt.Println("in the childs's for loop, the child's address here is:",&child)
node.Child = append(node.Child,child)
fmt.Println("in the child's for loop, after append the child is:",child)
if has(*child,vs) {
fmt.Println("i am in if has")
fmt.Println("the child in if has is:",*child)
fmt.Println("the child in if has 's address is:",child)
makeTree(vs,child)
}
}
}
func findChild(v *dept,vs []*dept)(ret []*dept) {
for _,v2 := range vs{
if v.FrameDeptStr+v.DeptId == v2.FrameDeptStr{
ret= append(ret,v2)
}
}
return
}
代碼備注:
通過frame_dept_str來確定科室之間的關(guān)系的, (a.frame_dept_str= a's parent's frame_dept_str + a's parent's dept_id).
補(bǔ)充:golang的樹結(jié)構(gòu)三種遍歷方式
看代碼吧~
package main
import "log"
type node struct {
Item string
Left *node
Right *node
}
type bst struct {
root *node
}
/*
m
k l
h i j
a b c d e f
//先序遍歷(根左右):m k h a b i c d l j e f
//中序遍歷(左根右):a h b k c i d m l e j f
//后序遍歷(左右根):a b h c d i k e f j l m
*/
func (tree *bst) buildTree() {
m := &node{Item: "m"}
tree.root = m
k := &node{Item: "k"}
l := &node{Item: "l"}
m.Left = k
m.Right = l
h := &node{Item: "h"}
i := &node{Item: "i"}
k.Left = h
k.Right = i
a := &node{Item: "a"}
b := &node{Item: "b"}
h.Left = a
h.Right = b
c := &node{Item: "c"}
d := &node{Item: "d"}
i.Left = c
i.Right = d
j := &node{Item: "j"}
l.Right = j
e := &node{Item: "e"}
f := &node{Item: "f"}
j.Left = e
j.Right = f
}
//先序遍歷
func (tree *bst) inOrder() {
var inner func(n *node)
inner = func(n *node) {
if n == nil {
return
}
log.Println(n.Item)
inner(n.Left)
inner(n.Right)
}
inner(tree.root)
}
//中序
func (tree *bst) midOrder() {
var inner func(n *node)
inner = func(n *node) {
if n == nil {
return
}
inner(n.Left)
log.Println(n.Item)
inner(n.Right)
}
inner(tree.root)
}
//后序
func (tree *bst) lastOrder() {
var inner func(n *node)
inner = func(n *node) {
if n == nil {
return
}
inner(n.Left)
inner(n.Right)
log.Println(n.Item)
}
inner(tree.root)
}
func main() {
tree := &bst{}
tree.buildTree()
// tree.inOrder()
tree.lastOrder()
}
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。如有錯誤或未考慮完全的地方,望不吝賜教。
相關(guān)文章
GoFrame?gtree樹形結(jié)構(gòu)的使用技巧示例
這篇文章主要為大家介紹了GoFrame?gtree樹形結(jié)構(gòu)的使用技巧示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-06-06
這些關(guān)于Go中interface{}的注意事項你都了解嗎
這篇文章主要為大家詳細(xì)介紹了學(xué)習(xí)Go語言時需要了解的interface{}注意事項,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起了解一下2023-03-03
go語言中切片與內(nèi)存復(fù)制 memcpy 的實現(xiàn)操作
這篇文章主要介紹了go語言中切片與內(nèi)存復(fù)制 memcpy 的實現(xiàn)操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-04-04
使用Lumberjack+zap進(jìn)行日志切割歸檔操作
這篇文章主要介紹了使用Lumberjack+zap進(jìn)行日志切割歸檔操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-12-12

