2-3 tree使用
The 2-3 tree is also a search tree like the binary search tree, but this tree tries to solve the problem of the unbalanced tree.
Imagine that you have a binary tree to store your data. The worst possible case for the binary tree is that all of the data is entered in order. Then the tree would look like this:
This tree has basically turned into a linked list. This is definitely a problem, for with a tree unbalanced like this, all of the advantages of the binary search tree disappear: searching the tree is slow and cumbersome, and there is much wasted memory because of the empty left child pointers.
浪费了存储空间。
The 2-3 tree tries to solve this by using a different structure and slightly different adding and removing procedure to help keep the tree more or less balanced. The biggest drawback with the 2-3 tree is that it requires more storage space than the normal binary search tree.
The 2-3 tree is called such because the maximum possible number of children each node can have is either 2 or 3. This makes the tree a bit more complex, so I will try to explain as much as possible.
One big difference with the 2-3 tree is that each node can have up to two data fields. You can see the three children extending from between the two data fields.
Thus, the tree is set up in the following manner:
- The node must always have a first field (data 1 in the diagram ), but not necessarily a second field (data 2). If both fields are present in a node, the first (or left) field of the node is always less than the second (or right) field of the node.
- Each node can have up to three child nodes, but if there is only one data field in the node, the node cannot have more than two children.
- The child nodes are set so that data in the first sub-tree is less than the first data field, the data of the second sub-tree is greater than the first data field and less than the second data field, and the data of the third sub-tree is greater than the second data field. If there is only one data field in the node, use the first and second children only.
- All leaf nodes appear on the last level.
Now, take a look at the implementation of a 2-3 tree:
class twoThreeTree {
public:
twoThreeTree(void); // Constructor
~twoThreeTree(void); // Destructor void add(int item); // Adds an item
void search(int item); //
Searches for an item private:
twoThreeNode *root; // Pointer to root node // Private helper functions go here
}; class twoThreeNode {
public:
int firstData, secondData; // Two data fields // The three child nodes
twoThreeNode *first, *second, *third; // This next one is quite useful. It aids
// moving around the tree. It is a pointer
// to the parent of the current node.
twoThreeNode *parent;
};
You can see that this tree, unlike the binary search tree or the heap tree, has no remove() function. It is possible to program a remove function, but it generally isn't worth the time or the effort.
This tree will be a bit harder to implement than the binary search tree just because of the complexity of the node. Still, the add() function algorithm isn'tthat difficult, and a step-by-step progression through the algorithm helps enormously.
First, to add an item, find the place in the tree for it. This is very much the same as in the binary search tree: just compare and move down the correct link until leaf node is reached.
Once at the leaf node, there are three basic cases for the add() function:
- The leaf node has only one data item: this case is very simple. Just insert the new item after this item or shift the old item forward and insert the new item before the old one, depending on the situation.
- The leaf node is full and the parent node has only one data item: this case is also quite simple. Compare the three values: the two leaf node items and the new item. Choose the middle one and insert it in the parent node where appropriate.
If the leaf node is the left child, shift the old data in the parent node to the right and insert the middle value in the parent node before the old data.Make sure to shift the pointers to the children in the parent node! If the leaf is the right child, just insert the middle value to the right of the old value in the parent node. The two left-over values from the comparison become two leaf nodes, one as the second child, and one as the first or third child depending on the situation.
- Both the leaf node and the parent node are full: this situation is the most complex of all. In the same manner as Case 2, promote the middle value of the leaf node. Then, continue doing the same thing with the parent node, and so on until the situation is resolved or the root node is reached. In this case, the middle value is promoted once again, except a new root node is created from the middle value and the two other values become the left and right subtrees of the new root. At the leaf node at which we began, the new level allows us to split the three initial values into a three node sub-tree of the parent node, and so on.
Doing a few small 2-3 trees by hand helps to understand this algorithm. Remember to check and hold to the rules governing the 2-3 tree! It can get ugly if they are ignored, especially with the last one.
Using some recursive helper functions as well as that miraculous parent variable will help ease the pain of programming this tree.
转自:http://www.cprogramming.com/tutorial/computersciencetheory/twothree.html
发现前面说的比较啰嗦,看wikipedia一目了然http://en.wikipedia.org/wiki/2%E2%80%933_tree
2-3tree有两种形式:
查找:
在进行2-3树的平衡之前,我们先假设已经处于平衡状态,我们先看基本的查找操作。
2-3树的查找和二叉查找树类似,要确定一个树是否属于2-3树,我们首先和其跟节点进行比较,如果相等,则查找成功;否则根据比较的条件,在其左中右子树中递归查找,如果找到的节点为空,则未找到,否则返回。查找过程如下图
插入
往一个2-node节点插入
往2-3树中插入元素和往二叉查找树中插入元素一样,首先要进行查找,然后将节点挂到未找到的节点上。2-3树之所以能够保证在最差的情况下的效率的原因在于其插入之后仍然能够保持平衡状态。如果查找后未找到的节点是一个2-node节点,那么很容易,我们只需要将新的元素放到这个2-node节点里面使其变成一个3-node节点即可。但是如果查找的节点结束于一个3-node节点,那么可能有点麻烦。
往一个3-node节点插入
往一个3-node节点插入一个新的节点可能会遇到很多种不同的情况,下面首先从一个最简单的只包含一个3-node节点的树开始讨论。
只包含一个3-node节点
如上图,假设2-3树只包含一个3-node节点,这个节点有两个key,没有空间来插入第三个key了,最自然的方式是我们假设这个节点能存放三个元素,暂时使其变成一个4-node节点,同时他包含四个子节点。然后,我们将这个4-node节点的中间元素提升,左边的节点作为其左节点,右边的元素作为其右节点。插入完成,变为平衡2-3查找树,树的高度从0变为1。
节点是3-node,父节点是2-node
和第一种情况一样,我们也可以将新的元素插入到3-node节点中,使其成为一个临时的4-node节点,然后,将该节点中的中间元素提升到父节点即2-node节点中,使其父节点成为一个3-node节点,然后将左右节点分别挂在这个3-node节点的恰当位置。操作如下图:
节点是3-node,父节点也是3-node
当我们插入的节点是3-node的时候,我们将该节点拆分,中间元素提升至父节点,但是此时父节点是一个3-node节点,插入之后,父节点变成了4-node节点,然后继续将中间元素提升至其父节点,直至遇到一个父节点是2-node节点,然后将其变为3-node,不需要继续进行拆分。
根节点分裂
当根节点到字节点都是3-node节点的时候,这是如果我们要在字节点插入新的元素的时候,会一直查分到跟节点,在最后一步的时候,跟节点变成了一个4-node节点,这个时候,就需要将跟节点查分为两个2-node节点,树的高度加1,这个操作过程如下:
本地转换
将一个4-node拆分为2-3node涉及到6种可能的操作。这4-node可能在跟节点,也可能是2-node的左子节点或者右子节点。或者是一个3-node的左,中,右子节点。所有的这些改变都是本地的,不需要检查或者修改其他部分的节点。所以只需要常数次操作即可完成2-3树的平衡。
性质
这些本地操作保持了2-3树的平衡。对于4-node节点变形为2-3节点,变形前后树的高度没有发生变化。只有当跟节点是4-node节点,变形后树的高度才加一。如下图所示:
转自:http://www.cnblogs.com/yangecnu/p/3624443.html
关于2-3tree的一个ppt:http://www.docin.com/p-621379239.html
“B-树”的“2-3树”的题目,望前辈指导!!!
题目是:
从空树开始,依次输入20,30,50,52,60,68,70,画出建立2-3树的过程。并分别画出删除50和68后的B-树状态。
书上说:通常取最小值m=3(度数,阶),此时B-树中每个内部结点可以有2或3个孩子,故将这种3阶的B-树称之为2-3树。
答案是:
答案给的是:
1〉 [20]
2〉 [20,30]
3〉 [30]
/ \
[20] [50]
4〉 [30]
/ \
[20] [50,52]
5〉 [30,52]
/ | \
[20] [50] [60]
6〉 [30,52]
/ | \
[20] [50] [60,68]
7〉 [30,52,68]
/ | \
[20] [50] [60,70]
8〉 [52]
/ \
[30] [68]
/ \ / \
[20][50][60][70]
转自:http://www.myexception.cn/arithmetic/256189.html
更多:
http://philoscience.iteye.com/blog/1401962
2-3 tree使用的更多相关文章
- [数据结构]——二叉树(Binary Tree)、二叉搜索树(Binary Search Tree)及其衍生算法
二叉树(Binary Tree)是最简单的树形数据结构,然而却十分精妙.其衍生出各种算法,以致于占据了数据结构的半壁江山.STL中大名顶顶的关联容器--集合(set).映射(map)便是使用二叉树实现 ...
- SAP CRM 树视图(TREE VIEW)
树视图可以用于表示数据的层次. 例如:SAP CRM中的组织结构数据可以表示为树视图. 在SAP CRM Web UI的术语当中,没有像表视图(table view)或者表单视图(form view) ...
- 无限分级和tree结构数据增删改【提供Demo下载】
无限分级 很多时候我们不确定等级关系的层级,这个时候就需要用到无限分级了. 说到无限分级,又要扯到递归调用了.(据说频繁递归是很耗性能的),在此我们需要先设计好表机构,用来存储无限分级的数据.当然,以 ...
- 2000条你应知的WPF小姿势 基础篇<45-50 Visual Tree&Logic Tree 附带两个小工具>
在正文开始之前需要介绍一个人:Sean Sexton. 来自明尼苏达双城的软件工程师.最为出色的是他维护了两个博客:2,000Things You Should Know About C# 和 2,0 ...
- Leetcode 笔记 110 - Balanced Binary Tree
题目链接:Balanced Binary Tree | LeetCode OJ Given a binary tree, determine if it is height-balanced. For ...
- Leetcode 笔记 100 - Same Tree
题目链接:Same Tree | LeetCode OJ Given two binary trees, write a function to check if they are equal or ...
- Leetcode 笔记 99 - Recover Binary Search Tree
题目链接:Recover Binary Search Tree | LeetCode OJ Two elements of a binary search tree (BST) are swapped ...
- Leetcode 笔记 98 - Validate Binary Search Tree
题目链接:Validate Binary Search Tree | LeetCode OJ Given a binary tree, determine if it is a valid binar ...
- Leetcode 笔记 101 - Symmetric Tree
题目链接:Symmetric Tree | LeetCode OJ Given a binary tree, check whether it is a mirror of itself (ie, s ...
- Tree树节点选中及取消和指定节点的隐藏
指定节点变色 指定节点隐藏 单击节点 未选中则选中该节点 已选中则取消该节点 前台: 1.HTML <ul id="listDept" name="listDept ...
随机推荐
- 解决 phpMyAdmin 尝试连接到 MySQL 服务器,但服务器拒绝连接 问题
phpMyAdmin 尝试连接到 MySQL 服务器,但服务器拒绝连接.您应该检查配置文件中的主机.用户名和密码,并确认这些信息与 MySQL 服务器管理员所给出的信息一致. 问题解决办法: 修改co ...
- asterisk webrtc使用SIPML5初体验
一直尝试,web呼叫xlite终端没有,主要是配置问题: 其中sip.conf配置如下: [general] context=public ; Default context for incoming ...
- A题笔记(12)
No.1466 代码:https://code.csdn.net/snippets/192091 No.1202 代码:https://code.csdn.net/snippets/192110 ...
- iOS 制作发布证书,发布到App Store
---恢复内容开始--- 1.登陆 iOS Dev Center 选择进入iOS Provisioning Portal. 2.在 iOS Provisioning Portal中,点击App IDs ...
- @Resource注解省略name属性后的行为
@Resource有一个name属性,该属性值为所要注入的Bean实例的id,类似于<property.../>元素的ref属性,不过在spring中允许省略name属性值,省略后在以下情 ...
- UDP协议疑难杂症全景解析
转载:http://blog.csdn.net/dog250/article/details/6896949 UDP协议疑难杂症全景解析 2011-10-22 19:26 2989人阅读 评论(4) ...
- e+开发中的各种问题
1.数据交换后走的查询公式还是controller所配置的公式
- 锋利的Jquery解惑系列(一)------基本概念大锅炖
声明:虽然是基本概念但也是笔者经过一番学习才总结的这些文章,所以他不包括Jquery优缺点.特点.语法的介绍. 概念一:jQuery对像与DOM对象 DOM(Document Object Model ...
- gitlab的安装以及汉化
gitlab的安装 首先在网上下载好任意版本gitlab的rpm包 推荐下面的地址: https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/el7/gi ...
- SQL Join(连接查询)
1.连接查询分为: inner join(自然连接,自连接) Left join(左连接)/Left outer join(左外连接):效果一样 Right join(右连接)/Right outer ...