树形结构数据构建算法

在一些前端开发过程中,我们通常需要将后台查询出来的集合数据进行相应的转换,转成树形结构对象,比如常用的评论区数据就是一种典型的树形结构数据,如下图所示。

《树形结构数据构建算法》

而后台服务端传来的数据通常是一种普通的集合(元素中有 id 和 pid ,以此构成 父子节点关系)它们是一种数组集合对象(服务端可能是List集合 ,前端为json对象或json串),如下图所示

[{
	"CODE": "6",
	"PID": "0",
	"ID": "6",
	"NAME": "天安门金领总校"
}, {
	"CODE": "101",
	"PID": "6",
	"ID": "101",
	"NAME": "校办"
}, {
	"CODE": "102",
	"PID": "6",
	"ID": "102",
	"NAME": "市场部"
}, {
	"CODE": "103",
	"PID": "6",
	"ID": "103",
	"NAME": "学术部"
}, {
	"CODE": "104",
	"PID": "6",
	"ID": "104",
	"NAME": "教质就业部"
}, {
	"CODE": "102101",
	"PID": "102",
	"ID": "102101",
	"NAME": "网咨部"
}, {
	"CODE": "102102",
	"PID": "102",
	"ID": "102102",
	"NAME": "媒体部"
}, {
	"CODE": "102103",
	"PID": "102",
	"ID": "102103",
	"NAME": "咨询部"
}, {
	"CODE": "103101",
	"PID": "103",
	"ID": "103101",
	"NAME": "教员组"
}, {
	"CODE": "104101",
	"PID": "104",
	"ID": "104101",
	"NAME": "班主任组"
}, {
	"CODE": "104102",
	"PID": "104",
	"ID": "104102",
	"NAME": "就业专员组"
}, {
	"CODE": "104103",
	"PID": "104",
	"ID": "104103",
	"NAME": "学员组"
}]

上面的json数据是平行结构(列表)最终在前端构成的展示数据是一棵树,如下图所示

《树形结构数据构建算法》

那么,我们如何将平行结构的数据转化成树型对象数据(平行二维列表数据转成有 N层次深度树形对象) 如下图所示

节点中如果有subnode属性,则表明该节点非叶子节点(拥有子节点),图中显示了树形对象的根节点,子节点,孙节点的关系

《树形结构数据构建算法》

这里涉及到常用算法参考如下

递归算法反复构建叶子节点,至到将数组内的所有节点加载到相匹配的父级节点下,具体js代码参数如下

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script lang="javascript">
var treelist = [{
	"CODE": "6",
	"PID": "0",
	"ID": "6",
	"NAME": "天安门金领总校"
}, {
	"CODE": "101",
	"PID": "6",
	"ID": "101",
	"NAME": "校办"
}, {
	"CODE": "102",
	"PID": "6",
	"ID": "102",
	"NAME": "市场部"
}, {
	"CODE": "103",
	"PID": "6",
	"ID": "103",
	"NAME": "学术部"
}, {
	"CODE": "104",
	"PID": "6",
	"ID": "104",
	"NAME": "教质就业部"
}, {
	"CODE": "102101",
	"PID": "102",
	"ID": "102101",
	"NAME": "网咨部"
}, {
	"CODE": "102102",
	"PID": "102",
	"ID": "102102",
	"NAME": "媒体部"
}, {
	"CODE": "102103",
	"PID": "102",
	"ID": "102103",
	"NAME": "咨询部"
}, {
	"CODE": "103101",
	"PID": "103",
	"ID": "103101",
	"NAME": "教员组"
}, {
	"CODE": "104101",
	"PID": "104",
	"ID": "104101",
	"NAME": "班主任组"
}, {
	"CODE": "104102",
	"PID": "104",
	"ID": "104102",
	"NAME": "就业专员组"
}, {
	"CODE": "104103",
	"PID": "104",
	"ID": "104103",
	"NAME": "学员组"
}];

function initTree(){   
   createTree(treelist);
}
//将传入的数据构建成树型对象
function createTree(treelist){
    // alert(treelist.length);
    // debugger;
    var treeData = new Array();
    for(var i = 0 ; i< treelist.length;i++){       
        //构建一级节点(根节点)
        if(treelist[i].PID == '0'){
            treeData.push(treelist[i]);
            console.log('构建一级节点:'+treelist[i].NAME);
            continue; //进入下一个元素处理
        }else{ //该元素非一级节点,将其挂在相应的节点下
            addNodeToTree(treelist[i],treeData);                
        }
    }
    console.log('tree对象构建完成');
    debugger;

}
//将node挂在treeData相应的节点下
function addNodeToTree(node ,treeData){
         for(var i = 0 ; i< treeData.length;i++){
             if(node.PID == treeData[i].ID){//说明是子节点
                if(typeof(treeData[i]["subnode"]) == "undefined"){
                    var subnode  = [];
                    subnode.push(node);
                    treeData[i]["subnode"] = subnode;  
                    console.log('给父节点:'+treeData[i].NAME+' 添加子节点:'+node.NAME+' 并集合化');
                    return true;
                }else{//该父节点已经存在子节点集合
                    treeData[i]["subnode"].push(node);
                    console.log('给父节点:'+treeData[i].NAME+' 添加子节点到集合:'+node.NAME);
                    return true;
                }            
             }
             //说明node节点不是该一级节点的子节点,如果该一级节点有子集合,则有可能是孙,重孙节点
            if(typeof(treeData[i]["subnode"]) != "undefined"){
                // console.log('需要检查该节点下的子集合 ID:'+treeData[i].ID+' name:'+treeData[i].NAME);
                // debugger;
                //开始递归              
                if(addNodeToTree(node,treeData[i]["subnode"])){
                    return true;
                }else{
                    continue;
                }
            }
         }
         console.log('该集合下未匹配到合适的节点:'+node.NAME);
        //  debugger;
         return false;

}
//将树型数据重新构造
</script>
</head>
<body onload="initTree()"> 
</body>
</html>

 

    原文作者:景天
    原文地址: https://blog.csdn.net/lixinyao5281/article/details/100067198
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞