多路查找树

本文介绍了多路查找树的基本概念,包括2-3树和2-3-4树的定义、插入及删除操作,并探讨了B树的概念。通过对2-3树等特殊树结构的研究,解决了传统二叉树在大量数据处理时可能出现的不平衡问题。

一.定义
二叉排序树简单的实现在多数情况能够达到预期的查找效率,但是每个节点只能存储一个元素和只能有两个孩子,使得在大量数据下会造成二叉排序树的深度特别大,那么在进行查找时多次的访问会造成查找效率的下降,同时,在对二叉查找树进行插入时,可能会破坏二叉查找树的平衡。为了降低对于树的访问次数,实现树的平衡,我们需要新的数据结构来处理这样的问题。
多路查找树的每一个节点的孩子树可以多于两个,且每个节点处可以存储多个元素。多路查找树是一种特殊的查找树,所以其元素之间存在某种特定的排序关系

二.2-3树
每个节点都具有2个孩子(称之为2节点)或者3个孩子(称之为3节点)
一个2节点包含一个元素和两个孩子(或没有孩子)
一个3节点包含两个元素和三个孩子(或没有孩子)
在这里插入图片描述
(一).插入实现
1.对于空树 插入一个节点直接插入就好
2.插入节点到一个2节点的叶子上
比如插入3
在这里插入图片描述
3.将一个节点插入到原来3节点的叶子上
3.1要在3节点上插入,此时3节点的上面是2节点 则将 上面的2节点变成3节点 比如插入5
在这里插入图片描述
3.2 要在3节点上插入,此时3节点上面是3 节点 则将上面首次出现为2节点的节点变成3节点。比如插入11
在这里插入图片描述
3.3 要在3节点插入数据时 ,该3节点往上遍历都是3节点,这时要扩展高度了
在这里插入图片描述
(二).删除实现
1.要删除的数位于3节点地址上。 3节点 ->2节点就好 比如删除6
在这里插入图片描述
在这里插入图片描述
2.要删除的数位于2叶子节点上
2.1此叶子节点上一级是2节点,但是他有一个3节点的有孩子。
在这里插入图片描述
2.2此叶子节点上一级是2节点,但是他有一个2节点的有孩子。
在这里插入图片描述
2.3此叶子节点双亲是一个3节点。
在这里插入图片描述
2.4删除的是一个满二叉树叶子节点
在这里插入图片描述
2.5要删除的元素位于非叶子节点的分支上。
①当是2节点时 则按照中序遍历 找此节点前面或者后面的数顶底下。
在这里插入图片描述
②当是3 节点的时候 将3节点的左孩子提升上去
在这里插入图片描述

三.2-3-4树
2-3-4树是对2-3树的概念扩展,包括了4节点的使用。一个4节点中包含小中大三个元素和四个孩子(要么有四个孩子要么没有,不存在其他情况)

四.B树
2-3树和2-3-4树是B树的特例
在这里插入图片描述

在这里插入图片描述
五.总结
1.先找插入结点,若结点有空(即2-结点),则直接插入。如结点没空(即3-结点),则插入使其临时容纳这个元素,然后分裂此结点,把中间元素移到其父结点中。对父结点亦如此处理。(中键一直往上移,直到找到空位,在此过程中没有空位就先搞个临时的,再分裂。)

2.2-3树插入算法的根本在于这些变换都是局部的:除了相关的结点和链接之外不必修改或者检查树的其他部分。每次变换中,变更的链接数量不会超过一个很小的常数。所有局部变换都不会影响整棵树的有序性和平衡性。

3.同时,通过上面树的深度增加的例子,可以看出2-3树和标准二叉树不同,标准的二叉树的的深度是由上到下的增加的,而2-3树的深度生长是由下至上的。

下面是一个简单的 Java 多路查找树(Trie)的代码示例: ```java public class Trie { private TrieNode root; public Trie() { root = new TrieNode(); } public void insert(String word) { TrieNode node = root; for (char c : word.toCharArray()) { if (node.children[c - 'a'] == null) { node.children[c - 'a'] = new TrieNode(); } node = node.children[c - 'a']; } node.isEndOfWord = true; } public boolean search(String word) { TrieNode node = root; for (char c : word.toCharArray()) { if (node.children[c - 'a'] == null) { return false; } node = node.children[c - 'a']; } return node.isEndOfWord; } public boolean startsWith(String prefix) { TrieNode node = root; for (char c : prefix.toCharArray()) { if (node.children[c - 'a'] == null) { return false; } node = node.children[c - 'a']; } return true; } private class TrieNode { private TrieNode[] children; private boolean isEndOfWord; public TrieNode() { children = new TrieNode[26]; } } } ``` 在这个示例中,我们定义了一个 Trie 类,其中包含一个内部 TrieNode 类,用于表示 Trie 树中的节点。TrieNode 类有一个布尔型变量 isEndOfWord,用于指示该节点是否是一个单词的结尾。Trie 类有三个方法:insert、search 和 startsWith。insert 方法用于将单词插入到 Trie 树中,search 方法用于查找单词是否在 Trie 树中,startsWith 方法用于查找是否存在以给定前缀开头的单词。 在 insert、search 和 startsWith 方法中,我们首先将指针 node 初始化为根节点。然后,对于单词中的每个字符,我们检查该字符的子节点是否存在。如果子节点不存在,则创建一个新的 TrieNode,并将其设置为该字符的子节点。最后,我们将指针 node 移动到该字符的子节点。在查找单词时,如果我们到达一个节点,其 isEndOfWord 变量为 true,则说明该单词在 Trie 树中,如果到达的节点没有对应的子节点,则该单词不在 Trie 树中。在查找以给定前缀开头的单词时,我们只需要检查 Trie 树中是否存在以该前缀开头的单词即可。 注意,在这个示例中,我们假设输入的单词只包含小写字母。如果输入包含其他字符,我们需要对代码进行适当的修改。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值