obsidian/笔记文件/2.笔记/前缀树红点_第一章.md
2025-03-26 00:02:56 +08:00

4.2 KiB
Raw Permalink Blame History

指的是,包含相同字符串前缀的,树结构,定义参考前缀树即可; 弄一个struct结构体RangeString继承自IEquatable泛型 结构体主要用于构造字符串作为前缀树的key索引相关 声明了源头的字符串、开始计算的字符串索引、结束计算的字符串索引、长度、判空、哈希码等变量;

!Pasted image 20240422173046.png

!Pasted image 20240422173238.png

构造函数,完成各变量的初始化

!Pasted image 20240422173309.png

继承自IEquatable其中必要的就是Equals函数接口 空字符、长度对比、还有基于索引 m_StartIndex 和 m_EndIndex 对比字符判断源字符m_Source对应索引的字符值是否相等判断返回true或false即可

!Pasted image 20240422173411.png

重写哈希值的逻辑是遍历源字符串m_Source的索引完成哈希值的重写逻辑

!Pasted image 20240423100542.png

游戏运行时会使用到ReddotMananger红点管理器的相关逻辑完成红点前缀树逻辑的增删触发等逻辑先弄一个对应的Instance单例

!Pasted image 20240423101218.png

其中有一个StringBuilder的字符串缓存器会用于范围字符串的Tostring重写

!Pasted image 20240423101414.png

回到RangeString范围字符串字符串的重写也是基于源字符串m_Source对应的Index索引使用 红点管理器的 CachedSb字符串缓存器完成构建重写即可

!Pasted image 20240423101526.png

TreeNode是前缀树的相关逻辑其中有一个m_Children的字典容器是以之前解析的RangeString范围字符串作为keyTreeNode树节点作为子value 该TreeNode树节点修改的函数回调是m_ChangeCallback的Action回调是红点数int的变更 m_FullPath完整路径指的是它在前缀树中的完整字符索引路径Name就是节点名

!Pasted image 20240423101726.png

Value就是对应的该节点包含的红点数值Parent就是它对应的父节点

!Pasted image 20240423104506.png

该TreeNode包含的子节点Values集合

!Pasted image 20240423104600.png

与之对应的还有子节点对应的总数如果m_Children数据容器为空直接返回0即可 否则就先把sum加上自身包含的m_Children子节点集合对应的Count数目 然后foreach遍历子节点集合的node节点sum再加上它们的子节点ChildrenCount总数

!Pasted image 20240423104648.png

先回到ReddotMananger红点管理器有声明3个节点集合分别对应所有可用的TreeNode前缀树节点字典容器m_AllNodes、脏节点数据容器m_DirtyNodes使用哈希HashSet确保其中包含的TreeNode元素唯一性后续会用于节点修改后对应的关联父节点触发红点修改回调 还有一个临时脏节点m_TempDirtyNodes数据容器是配合上述m_DirtyNodes完成缓冲和后续的脏节点逻辑处理 节点数量修改回调NodeNumChangeCallback、节点值改变回调NodeValueChangeCallback是对应后续触发编辑器的参数显示变更

!Pasted image 20240423103018.png

管理器还弄了一个char字符的SplitChar作为前缀树路径名称之间的分隔符

!Pasted image 20240423103939.png

还有一个Root根节点的设置、获取器

!Pasted image 20240423104021.png

ReddotMananger红点管理器的构造函数完成各变量的初始化完成了分隔符的定义是/根节点也是new实例化一个TreeNode的对象即可命名为"Root",还有几个数据容器、字符串缓存器的,初始化

!Pasted image 20240423104045.png

管理器中对应的MarkDirtyNode函数接口就是将对应的TreeNode节点加到m_DirtyNodes脏节点数据容器中

!Pasted image 20240423112516.png

回到TreeNode节点的逻辑类其中FullPath完整路径如果是Root根节点直接把Name作为完整路径即可 不 否则就配合父节点的FullPath完整路径 加上 SplitChar分隔符再加上自身Name构建即可

!Pasted image 20240423104306.png