由于本人正在建立个人博客网站,正涉及评论区功能数据结构,评论区的排布越看越像一颗树,所以采纳了树数据结构。
树
拆分理解:
每个子树结点也是往下层级的根结点,可结合下方数据结构理解
评论
这里是cnode中文社区部分评论区,有没有发现规律呢?
一条评论(包括顶端评论 [根结点] 及子评论 [子树结点] ) == 一棵树
评论区 == 多条评论 == 多棵树
评论区实际是遍历了多棵树。
代码演示
概念视图
/**
*
* A 根结点
* / \ \
* B C D 以下均为子树结点
* / / \
* E F G
* /\
* H I
* 问题: 按照字母由上至下,由左至右读取数据,模拟评论树数据结构,顺序:A B E F C G N I D
* 应用场景: 显示评论树
* 以下结构 中符号是 '|-' 是模拟设置css margin-left
* A、B ... 大写英文理解成一条评论中的评论内容:
* //程序输出:
* A
* |-B
* |-|-E
* |-|-F
* |-C
* |-|-G
* |-|-|-H
* |-|-|-I
* |-D
*
* 脑补评论区
* 第一条评论,也就是第一课树:
* A评论内容
* B评论A
* E评论B
* F评论B
* C评论A
* G评论C
* H评论G
* I评论G
* D评论A
*
* 第二条评论,也就是第二课树:
* A评论内容
* B评论A
* E评论B
* F评论B
* C评论A
* G评论C
* H评论G
* I评论G
* D评论A
*
* 思路:
* 方案: 先序遍历,递归
* 先取出根结点数据域,检测是否存在子树结点,存在则遍历,遇到null子结点返回,最后从左子结点树到右全遍历完则退出,从左到右实际是遍历子树结点数组默认左到右
* 递归边界: 最右最下子树节点为null或空数组
*
*/
算法demo
//树数据结构
const dataBase = {
val: "A", //数据域,根结点
childNode: [ //子树结点,数组
{
val: "B",
childNode: [
{
val: "E",
childNode: [
]
},
{
val: "F",
childNode: [
]
}
]
},
{
val: "C",
childNode: [
{
val: "G",
childNode: [
{
val: "H",
childNode: [
]
},
{
val: "I",
childNode: [
]
}
]
},
]
},
{
val: "D",
childNode: []
},
]
}
/**
* 遍历评论树
* @param {Objec} root 根结点
* @param {num} num 打印符号计算符号数,非核心算法
*
*/
function preorder(root, num) {
///打印用,非核心算法代码,前端可在这里设定父子评论样式//
let ss = '';
if(num > 0){
const newStrArr = new Array(num).fill("|-");
const strArr = newStrArr.join('')
ss = strArr;
}
////////////////////////
// 读取根结点数据域
console.log(`${ss}${root.val}`);
//设定边界,Boolean(root.childNode) === false
if (!root.childNode || (root.childNode && root.childNode.length === 0)) return;
num++;
//读取子结点树
for (let i = 0; i < root.childNode.length; i++) {
const item = root.childNode[i];
preorder(item, num);
}
}
function main(root) {
let num = 0;
preorder(root, num);
}
main(dataBase);
输出:
A
|-B
|-|-E
|-|-F
|-C
|-|-G
|-|-|-H
|-|-|-I
|-D