golang构造N叉树

2023-10-30

package main

import (
   "fmt"
   "strconv"
   "sync"
)

type Spaninfo struct {
   AppNames    []string               `json:"appNames"`
   ContainErr  bool                   `json:"containErr"`
   Attrs       map[string]interface{} `json:"attrs"`
   CspanMethod map[string]string      `json:"cspanid_method"`
   Cspanids    []string               `json:"cspanids"`
   EndTime     string                 `json:"endTime"` //Timestamp
   Host        []string               `json:"host"`
   LogName     []string               `json:"logName"`
   Message     []string               `json:"message"`
   OdinLeaf    []string               `json:"odinLeaf"`
   Spanid      string                 `json:"spanid"`
   StartTime   string                 `json:"startTime"` //Timestamp
   Su          []string               `json:"sus"`
   Traceid     string                 `json:"traceid"`
   URI         string                 `json:"uri"`
   //span级别聚合 有先后
   Broken   bool `json:"broken"`
   Duration int  `json:"duration"`
   //trace级别聚合 有先后
   Pspanid  string     `json:"pspanid"`
   Method   string     `json:"method"`
   Children []*Spaninfo `json:"children"`
}

func main() {
   m := sync.Map{}
   for i := 2; i < 10; i++ {
      s := Spaninfo{
         Spanid:  strconv.Itoa(i),
         Pspanid: strconv.Itoa(i - 1),
      }
      m.Store(strconv.Itoa(i), &s)
   }
   //组装完毕
   m.Store("1", &Spaninfo{Spanid: "1", Pspanid: ""})
   m.Store("11", &Spaninfo{Spanid: "11", Pspanid: ""})
   m.Store("11", &Spaninfo{Spanid: "12", Pspanid: "11"})
   root := &Spaninfo{}
   m.Range(func(ik, iv interface{}) bool {
      e := &Spaninfo{}
      if spaninfo, ok := iv.(*Spaninfo); ok {
         e = spaninfo
      } else {
         return true
      }
      pid := e.Pspanid
      if pid == "" {//将没有父节点的节点放倒根目录下
         root.Children = append(root.Children, e)
      }else {//把有父节点的节点,找到父节点,然后给父节点添加子节点
         ipnode,_ := m.Load(pid)
         pnode,_ :=  ipnode.(*Spaninfo)
         pnode.Children = append(pnode.Children,e)
      }

      return true
   })

   for _,r := range root.Children {
      //遍历树
      p := make([]string, 0)
      var ListP = make([][]string, 0, 10)

      ListPath(r, p, &ListP)
      fmt.Println("\n")
      for _, p := range ListP {
         for _, v := range p {
            fmt.Print(v, ",")
         }
      }
      fmt.Println("\n")
   }

}

//遍历树节点
func ListPath(root *Spaninfo, path []string, pathList *[][]string) {
   if root == nil {
      return
   }
   if root.Children == nil || len(root.Children) == 0 {
      path = append(path, root.Spanid)
      newPath := make([]string, len(path))
      copy(newPath, path) //这一步必须拷贝出来,不然path这个切片视图,如果值改变,会影响pathList的值
      *pathList = append(*pathList, newPath)
   } else {
      path = append(path, root.Spanid)
      childs := root.Children
      for _, v := range childs {
         ListPath(v, path, pathList)
      }
   }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

golang构造N叉树 的相关文章

随机推荐

  • C# 辗转相除法求最大公约数

    辗转相除法求最大公约数 public static void CalcGCD int largeNumber int smallNumber out int GCD GCD 1 int remain 1 while remain 0 rem
  • 推挽输出&&开漏输出

    在学习STM32的时候 我发现了一个很值得研究学习的问题 下面 用我的理解来阐述一遍 这其中的原理 首先请看电路图 在给GPIO配置输出的时候 其有两种工作模式可选 分别是推挽输出和开漏输出 在此之前先得了解mos管的工作原理 为了方便大家
  • 软件测试工作内容和职责有哪些

    目前 在IT行业中测试的职位数量仅次于开发 可以说是第二大技术就业岗位 然而许多人对测试师工作的理解还停留在 只需要像用户一样使用产品 然后发现有问题提交报告就行了 其实这是极其不准确的 软件测试师在测试产品前后通常有很多工作要做 下面我们
  • 计网笔记(1)- 计算机网络和因特网

    本章主要内容 构成网络的基本硬件和软件 我们将从网络的边缘开始 介绍网络中运行的端系统和网络应用 接下来探究网络的核心 介绍传输数据的链路和交换机 最后是连接端系统和网络核心的接入网和物理媒体 网络中数据的时延 丢包 吞吐量 计算机联网时的
  • stm32 串口发数据 0x00 变 0x80

    stm32 串口发数据 0x00 变 0x80 一般配置奇校验odd和偶校验even的时候 会出现这个问题 根本原因是stm32在计算长度的时候 会把校验位也计算进去 所以你之前设置的数据位8要改成数据位9才能正常运行 USART Init
  • Android Studio升级异常:Error : Program type already present: android.support.design.widget.CoordinatorLa

    解决的方案在build gradle增加 implementation com android support design 27 1 0 如图 最后Build一下就ok了 希望你跟我是一样的错误 能帮到你最好
  • [个人笔记]操作系统复习笔记

    一 绪论 OS的作用 用户与硬件之间的接口 管理计算机资源 抽象计算机资源 OS的发展 单道批处理系统 用户程序交给监控程序 由监控程序控制作业一个接一个交给IO处理 CPU等待IO 内存浪费 资源浪费 多道批处理系统 当一个作业在等待IO
  • 手动安装Kylin5.0版本的过程

    官方文档 https kylin apache org 目前kylin3 4版本是有docker版本和安装包的 5 0只有docker没有安装包 安装包 https kylin apache org download 安装kylin5 0
  • 56. 合并区间 57. 插入区间 66. 加一

    56 合并区间 以数组 intervals 表示若干个区间的集合 其中单个区间为 intervals i starti endi 请你合并所有重叠的区间 并返回 一个不重叠的区间数组 该数组需恰好覆盖输入中的所有区间 示例 1 输入 int
  • Win11怎么共享文件夹?Win11创建共享文件夹的方法

    共享文件夹能够实现在同一个局域网或者同一个工作组之内共享资源 这样不仅能够减少资源传递的时间 还可以提高工作效率 那么Win11怎么共享文件夹呢 还有详细的系统重装教程可阅读 具体操作如下 1 首先 按键盘上的 Win X 组合键 或右键点
  • FastDFS下载文件自定义命名

    上一节我们讲述了FastDFS的搭建和文件的上传 docker搭建FastDFS及遇到的问题解决 花开花落与云卷云舒的博客 CSDN博客 这一节我们讲讲如何将上传的文件下载到我们的本机并还原为原来的文件名 一 前言 在上一节中 我们知道我们
  • 最大权闭合子图的简单证明

    文章目录 一 概念 二 证明 2 1流网络的构造 2 2首先证明原图G的任何一个闭合子图都与新图 G G
  • docker报错WARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) afte

    完整报错 WARNING Retrying Retry total 4 connect None read None redirect None status None after connection broken by NewConne
  • springboot swagger2

    swagger2 介绍 Swagger Codegen 通过Codegen 可以将描述文件生成html格式和cwiki形式的接口文档 同时也能生成多钟语言的服务端和客户端的代码 支持通过jar包 docker node等方式在本地化执行生成
  • 查询练习题

    1 查询Student表中的所有记录的Sname Ssex和Class列 select Sname Ssex Class from Student 2 查询教师所有的单位即不重复的Depart列 select Depart count fr
  • AD20使用技巧和笔记

    AD20自学笔记 文章目录 AD20自学笔记 细节 规则 绘制PCB全流程 细节 AD20默认的铺铜 会出现相同网络的导线 如GND 将铺铜分隔开的情况 导致铜箔没有将区域完全覆盖 解决办法 选中铺铜区域 右键 属性 将 Pour Over
  • VS2022部署/安装 QT(以5.14.2为例)

    一 下载并安装Qt Visual Studio Tools 点击扩展 并选择管理扩展 二 搜索QT并下载Qt Visual Studio Tools 注意 如果wifi下载很慢 甚至不动 可以尝试用 热点 下载好后 关闭vs2022 它会自
  • Java基础 String StringBuffer StringBuilder的异同介绍

    一 String StringBuffer StringBuilder的对比 String StringBuffer StringBuilder 字符串类型 常量 不可变 变量 可变 变量 可变 线性安全 安全 final修饰 安全 方法s
  • 什么是PHP中的函数?它们如何使用?

    嘿 你好啊 PHP中的函数就像是一个超级有技能的工人 可以帮助我们更快更好地完成任务 它们就像是一个个工具箱 里面装满了各种用途的工具 函数可以执行各种任务 比如计算两个数的和 检查字符串是否包含某个字符 读取文件等等 使用函数可以让我们的
  • golang构造N叉树

    package main import fmt strconv sync type Spaninfo struct AppNames string json appNames ContainErr bool json containErr