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 slice元素去重操作
Apr 30 Golang
golang协程池模拟实现群发邮件功能
May 02 Golang
go语言使用Casbin实现角色的权限控制
Jun 26 Golang
Go 语言下基于Redis分布式锁的实现方式
Jun 28 Golang
golang 实用库gotable的具体使用
Jul 01 Golang
详解Go语言Slice作为函数参数的使用
Jul 02 Golang
Golang并发操作中常见的读写锁详析
Aug 30 Golang
golang使用map实现去除重复数组
Apr 14 Golang
golang的文件创建及读写操作
Apr 14 Golang
GO语言字符串处理函数之处理Strings包
Apr 14 Golang
Golang ort 中的sortInts 方法
Apr 24 Golang
在ubuntu下安装go开发环境的全过程
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
php实现简易聊天室应用代码
2015/09/23 PHP
Yii2增加验证码步骤详解
2016/04/25 PHP
PHP简单判断iPhone、iPad、Android及PC设备的方法
2016/10/11 PHP
PHP单例模式详解及实例代码
2016/12/21 PHP
js GridView 实现自动计算操作代码
2009/03/25 Javascript
JavaScript 函数式编程的原理
2009/10/16 Javascript
JS解决url传值出现中文乱码的另类办法
2013/04/08 Javascript
Js 导出table内容到Excel的简单实例
2013/11/19 Javascript
jquery中show()、hide()和toggle()用法实例
2015/01/15 Javascript
javascript组合使用构造函数模式和原型模式实例
2015/06/04 Javascript
jQuery+HTML5加入购物车代码分享
2020/10/29 Javascript
使用CoffeeScrip优美方式编写javascript代码
2015/10/28 Javascript
实用jquery操作表单元素的简单代码
2016/07/04 Javascript
javascript 使用正则test( )第一次是 true,第二次是false
2017/02/22 Javascript
JQuery实现图片轮播效果
2017/05/08 jQuery
[01:10:24]DOTA2-DPC中国联赛 正赛 VG vs Aster BO3 第一场 2月28日
2021/03/11 DOTA
Python标准库之collections包的使用教程
2017/04/27 Python
django基础之数据库操作方法(详解)
2017/05/24 Python
Python socket实现简单聊天室
2018/04/01 Python
pycharm远程linux开发和调试代码的方法
2018/07/17 Python
python2与python3共存问题的解决方法
2018/09/18 Python
Django-migrate报错问题解决方案
2020/04/21 Python
python可迭代对象去重实例
2020/05/15 Python
美国儿童玩具、装扮和玩偶商店:Magic Cabin
2018/09/02 全球购物
德国健康生活方式网上商店:Landkaufhaus Mayer
2019/03/12 全球购物
英国国家美术馆商店:National Gallery
2019/05/01 全球购物
打架检讨书400字
2014/01/17 职场文书
工作推荐信范文
2014/05/10 职场文书
副总经理岗位职责
2015/02/02 职场文书
食品质检员岗位职责
2015/04/08 职场文书
迎新晚会主持词开场白
2015/05/28 职场文书
2016大学生社会实践心得体会范文
2016/01/14 职场文书
创业计划书之烤红薯
2019/09/26 职场文书
为什么在foreach循环中JAVA集合不能添加或删除元素
2021/06/11 Java/Android
如何理解python接口自动化之logging日志模块
2021/06/15 Python
windows系统搭建WEB服务器详细教程
2022/08/05 Servers