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 相关文章推荐
win10下go mod配置方式
Apr 25 Golang
go结构体嵌套的切片数组操作
Apr 28 Golang
golang slice元素去重操作
Apr 30 Golang
关于golang高并发的实现与注意事项说明
May 08 Golang
Golang全局变量加锁的问题解决
May 08 Golang
详解Go语言Slice作为函数参数的使用
Jul 02 Golang
如何利用golang运用mysql数据库
Mar 13 Golang
Golang原生rpc(rpc服务端源码解读)
Apr 07 Golang
Go调用Rust方法及外部函数接口前置
Jun 14 Golang
Go Grpc Gateway兼容HTTP协议文档自动生成网关
Jun 16 Golang
GoFrame框架数据校验之校验结果Error接口对象
Jun 21 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
压力如何影响浓缩咖啡品质
2021/03/03 咖啡文化
php array_flip() 删除数组重复元素
2009/01/14 PHP
简单谈谈php中ob_flush和flush的区别
2014/11/27 PHP
PHP模板引擎Smarty内建函数详解
2016/04/11 PHP
php数据结构之顺序链表与链式线性表示例
2018/01/22 PHP
php操作mongodb封装类与用法实例
2018/09/01 PHP
制作特殊字的脚本
2006/06/26 Javascript
javascript编程起步(第三课)
2007/02/27 Javascript
js 中 document.createEvent的用法
2010/08/29 Javascript
浅析用prototype定义自己的方法
2013/11/14 Javascript
JavaScript字符串对象split方法入门实例(用于把字符串分割成数组)
2014/10/16 Javascript
再谈JavaScript异步编程
2016/01/27 Javascript
jQuery文件上传控件 Uploadify 详解
2016/06/20 Javascript
AngularJS递归指令实现Tree View效果示例
2016/11/07 Javascript
javascript实现无法关闭的弹框
2016/11/27 Javascript
Vue2 SSR渲染根据不同页面修改 meta
2017/11/20 Javascript
基于Vue2-Calendar改进的日历组件(含中文使用说明)
2019/04/14 Javascript
html+jQuery实现拖动滑块图片拼图验证码插件【移动端适用】
2019/09/10 jQuery
JavaScript实现栈结构Stack过程详解
2020/03/07 Javascript
详解Webpack抽离第三方类库以及common解决方案
2020/03/30 Javascript
详解Python nose单元测试框架的安装与使用
2017/12/20 Python
TensorFlow Session使用的两种方法小结
2018/07/30 Python
pygame游戏之旅 载入小车图片、更新窗口
2018/11/20 Python
python3.6下Numpy库下载与安装图文教程
2019/04/02 Python
使用TFRecord存取多个数据案例
2020/02/17 Python
Django2.1.7 查询数据返回json格式的实现
2020/12/29 Python
用CSS3打造HTML5的Logo(实现代码)
2016/06/16 HTML / CSS
详解使用canvas保存网页为pdf文件支持跨域
2018/11/23 HTML / CSS
一个J2EE项目团队的主要人员组成是什么
2012/06/04 面试题
四川成都导游欢迎词
2014/01/18 职场文书
小学生个人先进事迹材料
2014/05/08 职场文书
酒店管理专业毕业生自我鉴定
2014/09/29 职场文书
机械专业毕业生自我鉴定2014
2014/10/04 职场文书
2015年物资管理工作总结
2015/05/20 职场文书
优秀范文:读《红岩》有感3篇
2019/10/14 职场文书
springboot读取nacos配置文件
2022/05/20 Java/Android