树状列表数据-树状查询问题解决

最近在写的业务中,涉及了很多需求,需要将 sql 中的数据查询,然后根据 parentId 构建成树状结构。在实现这一需求的过程中,没有找到太好的解决方法,还在网站中提问,也暂时没有获得更好的回答结果。因此写下这篇文章,也希望能有大佬提供更好的思路,在此感谢。

提问地址:https://ask.csdn.net/questions/7953659?spm=1001.2014.3001.5501

实现一:遍历

最容易理解的方式,两个 for 循环,直接找 parentId = uid 的,加入子节点。

for(i : 1 to n) {
    for (j : 1 to n) {
        if (modeli.getUid().equals(modelj.getParentId())) {
            modeli.addChild(modelj);
        }
    }
}

时间复杂度 O(n^2),空间复杂度 O(1)

实现二:bfs遍历

实现二是对实现一的优化,将已经遍历过,成为父节点的节点,从待遍历队列中移除,从而达到降低时间复杂度的效果。

queue<model> solvedQueue;
queue<model> unsolvedQueue = new LinkedList<>();
List<model> rootList = new ArrayList<>();
// 预处理,将根节点提出
for(i : 1 to n) {
    if (modelList.get(i).getParentId() == null) {
        rootList.add(modeli);
    } else {
        unsolvedQueue.add(modeli);
    }
}
solvedQueue = new LinkedList(rootList);
while (!solvedQueue.isEmpty() && !unsolvedQueue.isEmpty()) {
    model = solvedQueue.poll();
    int length = unsolvedQueue.size();
    while((length--) > 0) {
        unsolvedModel = unsolvedQueue.poll();
        if (unsolvedModel.getParentId().equals(model.getUid)) {
            model.addChild(unsolvedModel);
            solvedQueue.add(unsolvedModel);
        } else {
            unsolvedQueue.add(unsolvedModel);
        }
    }
}
return rootList;

时间复杂度O(nlogn)?,空间复杂度O(n)

实现三:递归

找到根节点之后,递归每一层,获取子节点并存入,然后重复上述过程。 

List<model> rootList = new ArrayList<>();
for(i : 1 to n) {
    if (model.getParentId() == null) {
        rootList.add(model);
        buildTree(model, modelList);
    }
}


void buildTree(root, modelList) {
    if (root == null) {
        return;
    }
    for (i : 1 to n) {
        if (model.getParentId().equals(root.getUid)) {
            buildTree(model, modelList);
            root.addChild(model);
        }
    }
}

时间复杂度O(n^n),空间复杂度O(1) 

实现四:Map 偷渡

这种用于数据量较低的时候,可以简单实现。将 uid-model 保存为 map 键值对,然后只需要遍历一遍 map 就可以了。

Map<String, model> modelMap = new HashMap<>();
List<model> rootList;
for (i : 1 to n) {
    modelMap.put(model.getUid(), model);
    if (model.getParentId() == null) {
        rootList.add(model);
    }
}
for (model : modelMap.values()) {
    if (modelMap.exist(model.getParentId()) {
        modelMap.get(model.getParentId()).addChild(model);
    }
}
return rootList;

时间复杂度O(n),空间复杂度 O(n)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值