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语言求任意类型切片的长度操作
Apr 26 Golang
golang通过递归遍历生成树状结构的操作
Apr 28 Golang
golang 如何通过反射创建新对象
Apr 28 Golang
golang中的并发和并行
May 08 Golang
go使用Gin框架利用阿里云实现短信验证码功能
Aug 04 Golang
Go获取两个时区的时间差
Apr 20 Golang
Golang 结构体数据集合
Apr 22 Golang
Go语言入门exec的基本使用
May 20 Golang
Go gRPC进阶教程gRPC转换HTTP
Jun 16 Golang
GoFrame框架数据校验之校验结果Error接口对象
Jun 21 Golang
Python测试框架pytest核心库pluggy详解
Aug 05 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
thinkphp的静态缓存用法分析
2014/11/29 PHP
PHP实现对二维数组某个键排序的方法
2016/09/14 PHP
PHP+ajax实现获取新闻数据简单示例
2018/05/08 PHP
laravel5.1框架基础之Blade模板继承简单使用方法分析
2019/09/05 PHP
JQuery Tips(4) 一些关于提高JQuery性能的Tips
2009/12/19 Javascript
javascript+mapbar实现地图定位
2010/04/09 Javascript
JS操作Cookie写入和读取实例代码
2013/10/20 Javascript
基于jquery animate操作css样式属性小结
2015/11/27 Javascript
jQuery实现底部浮动窗口效果
2016/09/07 Javascript
AngularJS模板加载用法详解
2016/11/04 Javascript
jQuery实现的购物车物品数量加减功能代码
2016/11/16 Javascript
node.js 核心http模块,起一个服务器,返回一个页面的实例
2017/09/11 Javascript
Express的HTTP重定向到HTTPS的方法
2018/06/06 Javascript
详解angularjs跨页面传参遇到的一些问题
2018/11/01 Javascript
js实现淘宝首页的banner栏效果
2019/11/26 Javascript
vue 解决uglifyjs-webpack-plugin打包出现报错的问题
2020/08/04 Javascript
vue点击Dashboard不同内容 跳转到同一表格的实例
2020/11/13 Javascript
Python实现的简单发送邮件脚本分享
2014/11/07 Python
简单理解Python中基于生成器的状态机
2015/04/13 Python
python面试题之列表声明实例分析
2019/07/08 Python
python pip源配置,pip配置文件存放位置的方法
2019/07/12 Python
使用python绘制温度变化雷达图
2019/10/18 Python
详解Python可视化神器Yellowbrick使用
2019/11/11 Python
Python二元算术运算常用方法解析
2020/09/15 Python
美国最顶级的精品店之一:Hampden Clothing
2016/12/22 全球购物
荷兰天然和有机产品网上商城:BigGreenSmile.nl
2020/07/26 全球购物
医学专业毕业生个人的求职信
2013/12/04 职场文书
工作会议主持词
2014/03/17 职场文书
土建施工员岗位职责
2014/07/16 职场文书
个人贷款授权委托书样本
2014/10/07 职场文书
白酒代理协议书范本
2014/10/26 职场文书
2014年办公室主任工作总结
2014/11/12 职场文书
男方婚前保证书
2015/02/28 职场文书
辞职信范文大全
2015/03/02 职场文书
培训通知书模板
2015/04/17 职场文书
中国文明网2015年“向国旗敬礼”活动网上签名寄语
2015/09/24 职场文书