`
sunwinner
  • 浏览: 198003 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

基础数据结构和算法十:2-3 search tree

阅读更多

 

Binary search tree works well for a wide variety of applications, but they have poor worst-case performance. Now we introduce a type of binary search tree where costs are guaranteed to be logarithmic, no matter what sequence of keys is used to construct them. Ideally, we would like to keep our binary search trees perfectly balanced. In an N-node tree, we would like the height to be ~lg N so that we can guarantee that all searches can be completed in ~lg N compares, just as for binary search. Unfortunately, maintaining perfect balance for dynamic insertions is too expensive. In this section, we consider a data structure that slightly relaxes the perfect balance requirement to provide guaranteed logarithmic performance not just for the insert and search operations in our symbol-table API but also for all of the ordered operations (except range search).

 

 

The primary step to get the flexibility that we need to guarantee balance in search trees is to allow the nodes in our trees to hold more than one key. Specifically, referring to the nodes in a standard BST as 2-nodes (they hold two links and one key), we now also allow 3-nodes, which hold three links and two keys. Both 2-nodes and 3-nodes have one link for each of the intervals subtended by its keys. A 2-3 search tree is a tree that is either empty or

■ A 2-node, with one key (and associated value) and two links, a left link to a 2-3 search tree with smaller keys, and a right link to a 2-3 search tree with larger keys

■ A 3-node, with two keys (and associated values) and three links, a left link to a 2-3 search tree with smaller keys, a middle link to a 2-3 search tree with keys between the node’s keys, and a right link to a 2-3 search tree with larger keys

 

As usual, we refer to a link to an empty tree as a null link. A perfectly balanced 2-3 search tree is one whose null links are all the same distance from the root.

 

 

Search. The search algorithm for keys in a 2-3 tree directly generalizes the search al- gorithm for BSTs. To determine whether a key is in the tree, we compare it against the keys at the root. If it is equal to any of them, we have a search hit; otherwise, we follow the link from the root to the subtree corresponding to the interval of key values that could contain the search key. If that link is null, we have a search miss; otherwise we recursively search in that subtree.

 

 

Insert into a 2-node. To insert a new node in a 2-3 tree, we might do an unsuccessful search and then hook on the node at the bottom, as we did with BSTs, but the new tree would not remain perfectly balanced. The primary reason that 2-3 trees are useful is that we can do insertions and still main- tain perfect balance. It is easy to accomplish this task if the node at which the search terminates is a 2-node: we just replace the node with a 3-node containing its key and the new key to be inserted. If the node where the search terminates is a 3-node, we have more work to do.

 

Insert into a tree consisting of a single 3-node. As a first warmup before considering the general case, suppose that we want to insert into a tiny 2-3 tree consisting of just a single 3-node. Such a tree has two keys, but no room for a new key in its one node. To be able to perform the insertion, we temporarily put the new key into a 4-node, a natural extension of our node type that has three keys and four links. Creating the 4-node is convenient because it is easy to convert it into a 2-3 tree made up of three 2-nodes, one with the middle key (at the root), one with the smallest of the three keys (pointed to by the left link of the root), and one with the largest of the three keys (pointed to by the right link of the root). Such a tree is a 3-node BST and also a perfectly balanced 2-3 search tree, with all the null links at the same distance from the root. Before the insertion, the height of the tree is 0; after the insertion, the height of the tree is 1. This case is simple, but it is worth considering because it illustrates height growth in 2-3 trees.

 

 

Insert into a 3-node whose parent is a 2-node. As a second warmup,suppose that the search ends at a 3-node at the bottom whose parent is a 2-node. In this case, we can still make room for the new key while maintaining perfect balance in the tree, by making a temporary 4-node as just described, then splitting the 4-node as just described, but then, instead of creating a new node to hold the middle key, moving the middle key to the node’s parent. You can think of the transformation as replacing the link to the old 3-node in the parent by the middle key with links on either side to the new 2-nodes. By our assumption, there is room for doing so in the parent: the parent was a 2-node (with one key and two links) and becomes a 3-node (with two keys and three links). Also, this transformation does not affect the defining properties of (perfectly balanced) 2-3 trees. The tree remains or- dered because the middle key is moved to the parent, and it remains perfectly balanced: if all null links are the same distance from the root before the insertion, they are all the same distance from the root after the insertion. Be certain that you understand this transformation—it is the crux of 2-3 tree dynamics.

 

 

Insert into a 3-node whose parent is a 3-node. Now suppose that the search ends at a node whose parent is a 3-node. Again, we make a temporary 4-node as just described, then split it and insert its middle key into the parent. The parent was a 3-node, so we replace it with a temporary new 4-node containing the middle key from the 4-node split. Then, we perform precisely the same transformation on that node. That is, we split the new 4-node and insert its middle key into its parent. Extending to the general case is clear: we continue up the tree, splitting 4-nodes and inserting their middle keys in their parents until reaching a 2-node, which we replace with a 3-node that does not need to be further split, or until reaching a 3-node at the root.

 

 

Splitting the root. If we have 3-nodes along the whole path from the insertion point to the root, we end up with a temporary 4-node at the root. In this case we can proceed in precisely the same way as for insertion into a tree consisting of a single 3-node. We split the temporary 4-node into three 2-nodes, increasing the height of the tree by 1. Note that this last transformation preserves perfect balance because it is performed at the root.

 

 

Local transformations. Splitting a temporary 4-node in a 2-3 tree involves one of six transformations, summarized at the bottom of the next page. The 4-node may be the root; it may be the left child or the right child of a 2-node; or it may be the left child, middle child, or right child of a 3-node. The basis of the 2-3 tree insertion algorithm is that all of these transformations are purely local: no part of the tree needs to be examined or modified other than the specified nodes and links. The number of links changed for each transformation is bounded by a small constant. In particular, the transformations are effective when we find the specified patterns anywhere in the tree, not just at the bottom. Each of the transformations passes up one of the keys from a 4-node to that node’s parent in the tree and then restructures links accordingly, without touching any other part of the tree.

 

Global properties. Moreover, these local transformations preserve the global properties that the tree is ordered and perfectly balanced: the number of links on the path from the root to any null link is the same. For reference, a complete diagram illustrating this point for the case that the 4-node is the middle child of a 3-node is shown above. If the length of every path from a root to a null link is h before the transformation, then it is h after the transformation. Each transformation preserves this property, even while splitting the 4-node into two 2-nodes and while changing the parent from a 2-node to a 3-node or from a 3-node into a temporary 4-node. When the root splits into three 2-nodes, the length of every path from the root to a null link increases by 1. Another important properties of 2-3 search tree is, unlike standard BSTs, which grow down from the top, 2-3 trees grow up from the bottom. Search and insert operations in a 2-3 tree with N keys are guaranteed to visit at most lg N nodes.

 

 

Thus, we can guarantee good worst-case performance with 2-3 trees. The amount of time required at each node by each of the operations is bounded by a constant, and both operations examine nodes on just one path, so the total cost of any search or insert is guaranteed to be logarithmic.

 

 

However, we are only part of the way to an implementation. Although it is possible to write code that performs transformations on distinct data types representing 2- and 3-nodes, most of the tasks that we have described are inconvenient to implement in this direct representation because there are numerous different cases to be handled. We would need to maintain two different types of nodes, compare search keys against each of the keys in the nodes, copy links and other information from one type of node to another, convert nodes from one type to another, and so forth. Not only is there a substantial amount of code involved, but the overhead incurred could make the algorithms slower than standard BST search and insert. The primary purpose of balancing is to provide insurance against a bad worst case, but we would prefer the overhead cost for that insurance to be low. Fortunately, as you will see, we can do the transformations in a uniform way using little overhead with Red-Black tree.

分享到:
评论

相关推荐

    左程云leetcode-algorithm-and-data-structure:算法+数据结构=程序https://en.wikipedia

    数据结构和算法学习笔记 一、简介 1. 2. 3. 4. 5. 6. 二、数据结构 1. 二维数组(Array2D) 位数组(Bit Set) 静态数组(Fixed Size Array) 有序表(Ordered Array) 2. 队列(Queues) (后进先出) (先进先出)...

    01_Java版数据结构与算法 02_算法_直通BAT算法精讲

    数据结构1.pptx 2X1{SH5V_HSM`5JS[H]Z`JP.png 33XTI0U)]QTVK1MINJY0)F3.png 34MMEH64LMCA}H5G_RXKPGO.png 65]YTLJ{NP7ICB9{]%XK5J2.png 73I2ZJ(3Z5XWL3W1LFVZRCR.png MQJ[~8HPO2L{35`{CY8{WXO.png P)(%S5}WL7HD(09E1...

    左程云leetcode-algorithm-and-data-structure:算法+数据结构=程序

    数据结构和算法学习笔记 一、简介 1. 2. 3. 4. 5. 6. 二、数据结构 1. 二维数组(Array2D) 位数组(Bit Set) 静态数组(Fixed Size Array) 有序表(Ordered Array) 2. 队列(Queues) (后进先出) (先进先出)...

    c语言数据结构算法演示(Windows版)

    本课件是一个动态演示数据结构算法执行过程的辅助教学软件, 它可适应读者对算法的输入数据和过程执行的控制方式的不同需求, 在计算机的屏幕上显示算法执行过程中数据的逻辑结构或存储结构的变化状况或递归算法执行...

    数据结构算法演示(Windows版)

    本课件是一个动态演示数据结构算法执行过程的辅助教学软件, 它可适应读者对算法的输入数据和过程执行的控制方式的不同需求, 在计算机的屏幕上显示算法执行过程中数据的逻辑结构或存储结构的变化状况或递归算法执行...

    cs-algorithms:具有常用排序算法和数据结构的Python软件包

    CS算法目标主要目标是熟悉常见的算法和数据结构。 附加的好处是该代码将可访问和重用。档案结构algorithms/ -> numbers.py -> search.py -> sorting.py data_strucutes/ -> sequence.py -> tree.py安装方式pip ...

    学习数据结构算法必备

    数据结构算法演示 1. 顺序表 (1)在顺序表中插入一个数据元素(ins_sqlist) (2)删除顺序表中一个数据元素(del_sqlist) (3)合并两个有序顺序表(merge_sqlist) 2. 链表 (1)创建一个单链表(Crt_LinkList) ...

    严蔚敏 数据结构算法演示(Windows版)软件

    本课件是一个动态演示数据结构算法执行过程的辅助教学软件, 它可适应读者对算法的输入数据和过程执行的控制方式的不同需求, 在计算机的屏幕上显示算法执行过程中数据的逻辑结构或存储结构的变化状况或递归算法执行...

    数据结构演示软件

    本课件是一个动态演示数据结构算法执行过程的辅助教学软件, 它可适应读者对算法的输入数据和过程执行的控制方式的不同需求, 在计算机的屏幕上显示算法执行过程中数据的逻辑结构或存储结构的变化状况或递归算法执行...

    leetcode2-coding-exercises:我对有用数据结构、算法的实现,以及我对编程难题的解决方案

    这个存储库包含我对有用数据结构、算法、游戏的实现,以及我对编程难题的解决方案。 每个项目都标有难度级别。 1 - 简单 2 - 中等 3 - 困难 如果文件名以 'lc' 开头,则是来自 leetcode.com 的问题 用python3编写。 ...

    用c描述的数据结构演示软件

    本课件是一个动态演示数据结构算法执行过程的辅助教学软件, 它可适应读者对算法的输入数据和过程执行的控制方式的不同需求, 在计算机的屏幕上显示算法执行过程中数据的逻辑结构或存储结构的变化状况或递归算法执行...

    leetcode刷完300题-leetcode-beginner:leetcode算法和数据结构初学者刷题记录

    leetcode算法和数据结构初学者刷题记录 每个人的学习方法不同,找到最适合自己的方法就好了 200~300题刷2-3边,至少100+小时的投入 同一类型题目一起刷,总结规律和差异 参照表格里面的题目类型: 多看别人的(优秀...

    leetcode答案-CoreJava-:面试

    数据结构 抽象数据类型 计算复杂度分析 数组 链表 树排序 搜索算法 Boyer Moore 多数投票算法 面试准备 面试准备 书籍网络解决方案 CLRS 破解编程面试要素 编程语言 Python 竞争编码 Codechef Cookoff Long ...

    leetcode2-Leetcode_Notes:基于Python3的我的Leetcode笔记(中文)

    leetcode 2 Leetcode 总结 (基于Python3) 面试题目主要考察 ...数据结构的种类,以及在python3中的实现 < 基础 > List(顺序表): Array, String, Matrix Hash(哈希表): Dictionary (HashMap), Set (HashSe

    leetcode中文版-ts-datastructures-algorithms:和我一起学算法吧!

    数据结构 栈(Stack) 队列(Queue) 链表(Linked List) 树(Tree) 堆(Heap) 字典(Dictionary) 哈希表(Hash Table) 图(Graph) 3. 基本算法思维 枚举 递归 回溯 分治 贪心算法 试探算法 模拟算法 动态规划...

    数据结构实践

    2 线性表 顺序表 SqList 链表 单链表 LinkList 循环链表 ClinkList 双循环链表 DLinkList 静态链表 SlinkList 应用 集合并 MerGroup 多项式求和 Poly 3 栈 顺序栈 SqStack 链栈 LinkStack 栈应用 数制转换 ...

    STL 源码剖析(侯捷先生译著)

    那些数据结构、那些算法、那些重要观念、那些编程实务中最重要最根本的珍宝,那些蜇伏已久彷佛已经还给老师的记忆,将重新在你的脑中闪闪发光。 目录回到顶部↑庖丁解牛(侯捷自序) i 目录 v 前言 xvii 本书...

    leetcode旋转-coding_exercise:编码练习

    这个存储库包含我对有用数据结构、算法、游戏的实现,以及我对编程难题的解决方案。 每个项目都标有难度级别。 1 - 简单 2 - 中等 3 - 困难 如果文件名以 'lc' 开头,则是来自 leetcode.com 的问题 用python2编写 ...

    牛客的代码leetcode代码区别-coding-study:使用leetcode、niuke等编码

    (数据结构) List (线性表) LinkedList(链表) Tree(树) 2、leetcode (力扣) coding with leetcode 2.1 leetcode list id title created type 001 twoSum 2020/10/6 23:50 Array 206 ReverseNode 2020/10/8 0:...

Global site tag (gtag.js) - Google Analytics