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

业务场景:

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

解决办法:

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

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

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

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

(0)

相关推荐

  • golang遍历时修改被遍历对象的示例详解

    前言 很多时候需要将遍历对象中去掉某些元素,或者往遍历对象中添加元素,这时候就需要小心操作了. 对于go语言中的一些注意事项我做了总结和示例,留下点笔记. 遍历切片 1.遍历切片时去掉元素,错误示例: func main() { arr := []int{1, 2, 3, 4} for i := range arr { if arr[i] == 3 { arr = append(arr[:i], arr[i+1:]...) } } fmt.Println(arr) } 最终报错panic: ru

  • golang中for循环遍历channel时需要注意的问题详解

    前言 for循环是Go语言唯一的循环结构,最近在做一个基于RabbitMQ的应用,由于官方的qos没有golang的版本,所以出了一点问题. 问题代码如下: _, ch, err := component.NewRabbitMQ() if err != nil { panic(err) } if err := ch.Qos(10, 0, true); err != nil { panic(err) } msgs, err := ch.Consume("push", "&quo

  • 解决Golang map range遍历结果不稳定问题

    闲言少叙,本文主要是想介绍一个Golang开发常见的一个问题.然而,此问题对于初学者来说却经常容易陷入坑中. 问题 我在写一段代码时,使用了Golang的map数据结构,目的是想用map缓存计数结果.简单来说map的键也是整型的,且以递增顺序存储.我的最初想法是,在统计结束后,按照map中存储的键有序输出值.可是,当我运行程序时,结果并不是我想要的,而且有一定概率运行结果不同. 问题代码 func sortByBits(arr []int) []int { var bitmap = make(m

  • golang中range在slice和map遍历中的注意事项

    golang中range在slice和map遍历中的注意事项 package main import ( "fmt" ) func main() { slice := []int{0, 1, 2, 3} myMap := make(map[int]*int) for _,v :=range slice{ if v==1 { v=100 } } for k,v :=range slice{ fmt.Println("k:",k,"v:",v) }

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

    业务场景: 一个机构查询科室信息的时候,希望返回树状结构的嵌套格式; 解决办法: 通过递归和指针,嵌套成对应的结构体; 借鉴了前人的代码,但是最后递归的指针调用自己也是调试了半天才出来,这里献上完整的示例代码. package main import ( "fmt" "encoding/json" ) type dept struct { DeptId string `json:"deptId"` FrameDeptStr string `jso

  • 利用Django模版生成树状结构实例代码

    前言 我们经常会有这样的需求,比如评论功能,每个评论都有可能会有自己的子评论,如果在界面只展示成一列的话非常不美观,也不能体现出他们的层级关系.那么我们今天就来看看如何使用Django的模版来生成树状结构,以本站为例,效果如下图所示: 那么我们要怎么实现呢?首先先看看评论实体的定义,如下所示: class Comment(models.Model): body = models.TextField('正文', max_length=300) author = models.ForeignKey(

  • 用Python编写生成树状结构的文件目录的脚本的教程

    有时候需要罗列下U盘等移动设备或一个程序下面的目录结构的需求.基于这样的需求个人整理了一个使用Python的小工具,期望对有这方面需求的朋友有所帮助.以下为具体代码: 如果你所有要求的文件目录不需要完整的文件路径的话,直接更换下面的注释代码即可~ # -*- coding:utf-8 -*- import os def list_files(startPath): fileSave = open('list.txt','w') for root, dirs, files in os.walk(s

  • Python 无限级分类树状结构生成算法的实现

    后端研发的同学对无限级分类肯定映像深刻,当初花了不少时间吧? 无限级分类树状结构的应用场景很多,例如后端研发需要把用户相关权限读取出来并生成树状结构,前端研发拿到权限树之后可以按照结构展示用户有权限访问的栏目:再例如网页上的栏目分级: 作者在初次接触树状结构生成需求的时候,也是挠头,后来找到了一个代码少且清晰易懂的生成算法:递归. 首先,确保数据库中存储的类别信息如下: [ {"id": 1, "name": '电器', "parent": 0}

  • Java递归遍历树形结构

    废话不多说了,直接给大家贴代码,具体代码如下所示: //菜单树形结构 public JSONArray treeMenuList(JSONArray menuList, int parentId) { JSONArray childMenu = new JSONArray(); for (Object object : menuList) { JSONObject jsonMenu = JSONObject.fromObject(object); int menuId = jsonMenu.ge

  • PyQt5 QTreeWidget 树形结构递归遍历当前所有节点的实现

    目录 QTreeWidget类中的常用方法 QTreeWidgetItem类中的常用方法 准备一个小demo 这样的做法有什么好处和坏处? 对比网上的方法 QTreeWidget类中的常用方法 方法 描述 setColumnWidth(int column,int width) 将指定列的宽度设置为给定的值width insertTopLevelItems() 在视图的顶层索引中插入项目列表 expandAll() 展开所有的树形节点 invisibleRootItem() 返回树形控件中不可见

  • Java递归遍历树形结构的实现代码

    废话不多说了,直接给大家贴代码,具体代码如下所示: //菜单树形结构 public JSONArray treeMenuList(JSONArray menuList, int parentId) { JSONArray childMenu = new JSONArray(); for (Object object : menuList) { JSONObject jsonMenu = JSONObject.fromObject(object); int menuId = jsonMenu.ge

  • react+antd 递归实现树状目录操作

    1.写在前面 作为前端小白的我一直对算法和数据结构浅尝辄止,哝,吃亏了.使用多次递归实现数据格式化后将数据进行树状展示的目的,分享一下我这次挠头的经历~ 2.数据 后台传过来的数据大概是这样的 { "data":[ { "id":1, "name":"一级节点", "parentId":0, "isValid":true, "canAddChild":true, &q

  • JS递归遍历查询是否有权限示例详解

    目录 前言 需求分析 设计思路 代码 声明查找模板如下 js 版本 ts 版本 后记 前言 最近参与了一个基于 qiankun 构建的微前端大型项目,涉及到十几个子应用,基于基座独立开发了一个完善的权限中心模块.而权限中心中涉及到了 模块 > 一级菜单 > N级菜单/按钮 结构的权限管理. 这次的需求是在其中一个子应用的按钮级别的权限管理,在鉴权阶段写了一个小的方法,用来从权限树中查询是否有某一个按钮的权限,从而控制用户对于按钮的使用权限. 需求分析 权限的每一层对应的子菜单的键不尽相同. 在

  • 实现树状结构的两种方法

    实现树状结构的两种方法 1.递归法递归是指在函数中显式的调用它自身.利用递归法实现树状结构的特点是写入数据速度较快,显示速度较慢(在树的分支/层次较多的情况下尤其明显).适用与写入数据量大,树的结构复杂的情况下.数据结构(以mysql为例) 代码:--------------------------------------------------------------------------------CREATE TABLE `tree1` (  `id` tinyint(3) unsign

随机推荐