golang通过递归遍历生成树状结构的操作


Posted in Golang onApril 28, 2021

业务场景:

一个机构查询科室信息的时候,希望返回树状结构的嵌套格式;

解决办法:

通过递归和指针,嵌套成对应的结构体;

借鉴了前人的代码,但是最后递归的指针调用自己也是调试了半天才出来,这里献上完整的示例代码.

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来确定科室之间的关系的, (a.frame_dept_str= a's parent's frame_dept_str + a's parent's dept_id).

补充:golang的树结构三种遍历方式

看代码吧~

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()
}

以上为个人经验,希望能给大家一个参考,也希望大家多多支持三水点靠木。如有错误或未考虑完全的地方,望不吝赐教。

Golang 相关文章推荐
golang判断key是否在map中的代码
Apr 24 Golang
win10下go mod配置方式
Apr 25 Golang
Golang 正则匹配效率详解
Apr 25 Golang
Go语言带缓冲的通道实现
Apr 26 Golang
对Golang中的FORM相关字段理解
May 02 Golang
golang elasticsearch Client的使用详解
May 05 Golang
golang 实现时间戳和时间的转化
May 07 Golang
基于Go语言构建RESTful API服务
Jul 25 Golang
Golang表示枚举类型的详细讲解
Sep 04 Golang
Golang中channel的原理解读(推荐)
Oct 16 Golang
详解Go语言中Get/Post请求测试
Jun 01 Golang
Go gorilla securecookie库的安装使用详解
Aug 14 Golang
goland 恢复已更改文件的操作
goland 清除所有的默认设置操作
go 原生http web 服务跨域restful api的写法介绍
Apr 27 #Golang
解决Golang中ResponseWriter的一个坑
Apr 27 #Golang
golang在GRPC中设置client的超时时间
golang http使用踩过的坑与填坑指南
Apr 27 #Golang
Golang 实现超大文件读取的两种方法
Apr 27 #Golang
You might like
YII中assets的使用示例
2014/07/31 PHP
PHP PDO和消息队列的个人理解与应用实例分析
2019/11/25 PHP
PHP基于进程控制函数实现多线程
2020/12/09 PHP
由浅到深了解JavaScript类
2006/09/08 Javascript
jQuery ReferenceError: $ is not defined 错误的处理办法
2013/05/10 Javascript
jquery用get实现ajax在ie里面刷新不进入后台解决方法
2013/08/12 Javascript
将json对象转换为字符串的方法
2014/02/20 Javascript
利用jquery操作Radio方法小结
2014/10/20 Javascript
JavaScript调用浏览器打印功能实例分析
2015/07/17 Javascript
jQuery中serializeArray()与serialize()的区别实例分析
2015/12/09 Javascript
bootstrap table方法之expandRow-collapseRow展开或关闭当前行数据
2020/08/09 Javascript
JS实现点击循环切换显示内容的方法
2017/10/19 Javascript
详解如何使用koa实现socket.io官网的例子
2018/11/04 Javascript
Vue 自适应高度表格的实现方法
2020/05/13 Javascript
python将字符串转换成数组的方法
2015/04/29 Python
深入浅析Python字符编码
2015/11/12 Python
实践Python的爬虫框架Scrapy来抓取豆瓣电影TOP250
2016/01/20 Python
python3判断url链接是否为404的方法
2018/08/10 Python
对Python 多线程统计所有csv文件的行数方法详解
2019/02/12 Python
深入浅析Python 函数注解与匿名函数
2020/02/24 Python
HTML5 placeholder属性详解
2016/06/22 HTML / CSS
菲律宾领先的在线时尚商店:Zalora菲律宾
2018/02/08 全球购物
报关简历自我评价怎么写
2013/09/19 职场文书
工业自动化专业毕业生推荐信
2013/11/18 职场文书
出纳岗位职责范本
2013/12/01 职场文书
应届优秀本科大学毕业生自我鉴定
2014/01/21 职场文书
技能竞赛活动方案
2014/02/21 职场文书
社区学习雷锋活动总结
2014/04/25 职场文书
学前班幼儿评语大全
2014/12/29 职场文书
世界地球日活动总结
2015/02/09 职场文书
医生个人年度总结
2015/02/28 职场文书
2015年助理政工师工作总结
2015/05/26 职场文书
小学生读书笔记
2015/07/01 职场文书
退休欢送会主持词
2015/07/01 职场文书
html form表单基础入门案例讲解
2021/07/21 HTML / CSS
使用Ajax实现进度条的绘制
2022/04/07 Javascript