树缩减算法

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了树缩减算法相关的知识,希望对你有一定的参考价值。

背景:今天有这么一个需求就是叶节点数量只有一个而且深度太深造成了用户反感,需要缩减深度。

技术分享图片

最终目标:1’替换2,2’替换4,3’替换8

数据结构:父节点持有子节点的list,子节点持有父节点的id,不是父节点本身,这样是因为循环引用在转json时会造成麻烦。

public void shrinkTree() {
        //根节点有孩子
        if (!nodes.isEmpty()) {
            final Iterator<KnowledgeInfo> iterator = nodes.iterator();
            while (iterator.hasNext()) {
                final KnowledgeInfo self = iterator.next();
                shrinkTree(this, self, self);
            }
        }

    }

    /**
     * @param lastRoot 最近的一个多孩子父节点
     * @param remove   父节点到叶节点之间的一个节点 可能是叶节点本身,如果不是叶节点则可能是要删除的节点
     * @param self     当前节点
     */
    private void shrinkTree(KnowledgeInfo lastRoot, KnowledgeInfo remove, KnowledgeInfo self) {
        if (self.nodes == null || self.nodes.isEmpty()) {
            return;
        }
        //有独生子
        if (self.nodes.size() == 1) {
            final KnowledgeInfo knowledgeInfo = self.nodes.get(0);
            //独生子已经是最末端了
            //和最近根下的祖宗节点交换
            if (knowledgeInfo.isLeaf == 1) {
                final int index = lastRoot.nodes.indexOf(remove);
                knowledgeInfo.setParentId(lastRoot.getId());
                knowledgeInfo.setDepth((byte) (lastRoot.getDepth() + 1));
                lastRoot.nodes.set(index, knowledgeInfo);
                //不是独生子还有孩子
            } else {
                shrinkTree(lastRoot, remove, knowledgeInfo);
            }
            //有多个孩子根节点切换
        } else {
            final Iterator<KnowledgeInfo> iterator = self.nodes.iterator();
            while (iterator.hasNext()) {
                final KnowledgeInfo next = iterator.next();
                if (next.isLeaf == 0) {
                    shrinkTree(self, next, next);
                }
            }
        }
    }

 

以上是关于树缩减算法的主要内容,如果未能解决你的问题,请参考以下文章

算法基础5:希尔排序(缩减增量排序算法)

以下代码片段的算法复杂度

VLSI数字信号处理系统——第九章滤波器和变换中的算法强度缩减

有人可以解释啥是 SVN 平分算法吗?理论上和通过代码片段[重复]

基础算法模板之二分

片段(Java) | 机试题+算法思路+考点+代码解析 2023