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 相关文章推荐
Go语言使用select{}阻塞main函数介绍
Apr 25 Golang
Go标准容器之Ring的使用说明
May 05 Golang
golang switch语句的灵活写法介绍
May 06 Golang
golang 实现时间戳和时间的转化
May 07 Golang
聊聊golang中多个defer的执行顺序
May 08 Golang
GoLang中生成UUID唯一标识的实现
May 08 Golang
go web 预防跨站脚本的实现方式
Jun 11 Golang
go select编译期的优化处理逻辑使用场景分析
Jun 28 Golang
Go语言空白表示符_的实例用法
Jul 04 Golang
详解Golang如何优雅的终止一个服务
Mar 21 Golang
Go 内联优化让程序员爱不释手
Jun 21 Golang
go goth封装第三方认证库示例详解
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
PHP 加密解密内部算法
2010/04/22 PHP
一些被忽视的PHP函数(简单整理)
2010/04/30 PHP
jQuery1.3.2 升级到jQuery1.4.4需要修改的地方
2011/01/06 Javascript
jquery实现兼容浏览器的图片上传本地预览功能
2013/10/14 Javascript
通过实例理解javascript中没有函数重载的概念
2015/06/03 Javascript
JS实现仿腾讯微博无刷新删除微博效果代码
2015/10/16 Javascript
javascript中去除数组重复元素的实现方法【实例】
2016/04/12 Javascript
javascript实现简易计算器
2017/02/01 Javascript
JS实现的tab切换选项卡效果示例
2017/02/28 Javascript
win系统下nodejs环境安装配置
2017/05/04 NodeJs
javaScript canvas实现(画笔大小 颜色 橡皮的实例)
2017/11/28 Javascript
JavaScript常用截取字符串的三种方式用法区别实例解析
2018/05/15 Javascript
vue项目使用axios发送请求让ajax请求头部携带cookie的方法
2018/09/26 Javascript
mocha的时序规则讲解
2019/02/16 Javascript
对vuex中getters计算过滤操作详解
2019/11/06 Javascript
微信小程序swiper组件实现抖音翻页切换视频功能的实例代码
2020/06/24 Javascript
如何在Vue项目中添加接口监听遮罩
2021/01/25 Vue.js
[01:57]2018年度DOTA2最具潜力解说-完美盛典
2018/12/16 DOTA
[45:25]OG vs EG 2019国际邀请赛淘汰赛 胜者组 BO3 第一场 8.22
2019/09/05 DOTA
Python 文件管理实例详解
2015/11/10 Python
Python Web框架Tornado运行和部署
2020/10/19 Python
详解python中executemany和序列的使用方法
2017/08/12 Python
Python SQL查询并生成json文件操作示例
2018/08/17 Python
python numpy元素的区间查找方法
2018/11/14 Python
aws 通过boto3 python脚本打pach的实现方法
2020/05/10 Python
Python+Dlib+Opencv实现人脸采集并表情判别功能的代码
2020/07/01 Python
AHAVA美国官方网站:死海海泥护肤品牌
2016/10/18 全球购物
护士实习自我鉴定
2013/10/22 职场文书
怎么样写好简历中的自我评价
2013/10/25 职场文书
物业管理个人自我评价
2013/11/08 职场文书
文员岗位职责
2013/11/09 职场文书
销售经理岗位职责
2014/03/16 职场文书
高中学生期末评语
2014/04/25 职场文书
安全先进个人材料
2014/12/29 职场文书
如何写一份具有法律效力的借款协议书?
2019/07/02 职场文书
Vue3中的Refs和Ref详情
2021/11/11 Vue.js