利用引用传递一次遍历构造菜单树(附java&go demo)

原理讲解

利用引用传递,当儿子的儿子变动的时候,自己的儿子的儿子也变动(取地址)

java demo

package com.huiyuan.algorithm;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

public class Tree {
    public static void main(String[] args) {
        List<TreeDto> treeDtoList = new ArrayList<>() {{
            add(new TreeDto(1, 0, "111"));
            add(new TreeDto(3, 2, "333"));
            add(new TreeDto(2, 1, "222"));
            add(new TreeDto(4, 2, "444"));
        }};

        Map<Integer, TreeDto> treeDtoMap = treeDtoList.stream().collect(Collectors.toMap(TreeDto::getId, Function.identity()));

        for (Map.Entry<Integer, TreeDto> entry : treeDtoMap.entrySet()) {
            int pid = entry.getValue().getPid();

            if(treeDtoMap.containsKey(pid)){
                if(treeDtoMap.get(pid).getChildren() == null){
                    treeDtoMap.get(pid).setChildren(new ArrayList<>());
                }

                treeDtoMap.get(pid).getChildren().add(entry.getValue());
            }
        }

        System.out.println(treeDtoMap);
    }
}

class TreeDto {
    private int id;
    private int pid;
    private String name;
    private List<TreeDto> children;

    @Override
    public String toString() {
        return "TreeDto{" +
                "id=" + id +
                ", pid=" + pid +
                ", name='" + name + '\'' +
                ", children=" + children +
                '}';
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<TreeDto> getChildren() {
        return children;
    }

    public void setChildren(List<TreeDto> children) {
        this.children = children;
    }

    public int getId(){
        return this.id;
    }

    public int getPid(){
        return this.pid;
    }

    public TreeDto(int id, int pid, String name) {
        this.id = id;
        this.pid = pid;
        this.name = name;
    }
}

Go demo

package main

import "fmt"

type treeDto struct {
	Id       int32
	Pid      int32
	Name     string
	Children []*treeDto
}

func main() {
	treeDtoMap := make(map[int32]*treeDto)

	treeDtoMap[1] = &treeDto{
		Id:   1,
		Pid:  0,
		Name: "111",
	}

	treeDtoMap[4] = &treeDto{
		Id:   4,
		Pid:  2,
		Name: "444",
	}

	treeDtoMap[2] = &treeDto{
		Id:   2,
		Pid:  1,
		Name: "222",
	}

	treeDtoMap[3] = &treeDto{
		Id:   3,
		Pid:  2,
		Name: "333",
	}

	for _, tree := range treeDtoMap {
		pid := tree.Pid

		if _, ok := treeDtoMap[pid]; ok {
			treeDtoMap[pid].Children = append(treeDtoMap[pid].Children, tree)
		}
	}

	fmt.Println(treeDtoMap)
}

优点

  • 时间复杂度为O(n),亲测可支持几百万的节点树
  • 过程中产生的副产品,在getChildren()的时候可以直接获取
posted @ 2023-02-03 15:32  源源猿  阅读(38)  评论(0编辑  收藏  举报