剑指XX游戏(六) - 轻松搞定面试中的红黑树问题
原文地址 http://blog.csdn.net/silangquan/article/details/18655795?utm_source=tuicool&utm_medium=referral
连续两次面试都问到了红黑树,关键两次都没有答好,这次就完整地来学习整理一下。
没有学习过红黑树的同学请参考:
<<Introduction to Algorithms>> Chapter 13 Red-Black Trees Chapter 14 Augmenting Data Structures
1.stl中的set底层用的什么数据结构?
2.红黑树的数据结构怎么定义的?
3.红黑树有哪些性质?
4.红黑树的各种操作的时间复杂度是多少?
5.红黑树相比于BST和AVL树有什么优点?
6.红黑树相对于哈希表,在选择使用的时候有什么依据?
7.如何扩展红黑树来获得比某个结点小的元素有多少个?
8.扩展数据结构有什么步骤?
详细解答
1.stl中的set底层用的什么数据结构?
红黑树
2.红黑树的数据结构怎么定义?
plain
- enum Color
- {
- RED = 0,
- BLACK = 1
- };
- struct RBTreeNode
- {
- struct RBTreeNode*left, *right, *parent;
- int key;
- int data;
- Color color;
- };
3.红黑树有哪些性质?
一般的,红黑树,满足以下性质,即只有满足以下全部性质的树,我们才称之为红黑树:
1)每个结点要么是红的,要么是黑的。
2)根结点是黑的。
3)每个叶结点(叶结点即指树尾端NIL指针或NULL结点)是黑的。
4)如果一个结点是红的,那么它的俩个儿子都是黑的。
5)对于任一结点而言,其到叶结点树尾端NIL指针的每一条路径都包含相同数目的黑结点。
4.红黑树的各种操作的时间复杂度是多少?
能保证在最坏情况下,基本的动态几何操作的时间均为O(lgn)
5.红黑树相比于BST和AVL树有什么优点?
红黑树是牺牲了严格的高度平衡的优越条件为代价,它只要求部分地达到平衡要求,降低了对旋转的要求,从而提高了性能。红黑树能够以O(log2 n)的时间复杂度进行搜索、插入、删除操作。此外,由于它的设计,任何不平衡都会在三次旋转之内解决。当然,还有一些更好的,但实现起来更复杂的数据结构能够做到一步旋转之内达到平衡,但红黑树能够给我们一个比较“便宜”的解决方案。
相比于BST,因为红黑树可以能确保树的最长路径不大于两倍的最短路径的长度,所以可以看出它的查找效果是有最低保证的。在最坏的情况下也可以保证O(logN)的,这是要好于二叉查找树的。因为二叉查找树最坏情况可以让查找达到O(N)。
红黑树的算法时间复杂度和AVL相同,但统计性能比AVL树更高,所以在插入和删除中所做的后期维护操作肯定会比红黑树要耗时好多,但是他们的查找效率都是O(logN),所以红黑树应用还是高于AVL树的. 实际上插入 AVL 树和红黑树的速度取决于你所插入的数据.如果你的数据分布较好,则比较宜于采用 AVL树(例如随机产生系列数),但是如果你想处理比较杂乱的情况,则红黑树是比较快的
6.红黑树相对于哈希表,在选择使用的时候有什么依据?
权衡三个因素: 查找速度, 数据量, 内存使用,可扩展性。
总体来说,hash查找速度会比map快,而且查找速度基本和数据量大小无关,属于常数级别;而map的查找速度是log(n)级别。并不一定常数就比log(n) 小,hash还有hash函数的耗时,明白了吧,如果你考虑效率,特别是在元素达到一定数量级时,考虑考虑hash。但若你对内存使用特别严格, 希望程序尽可能少消耗内存,那么一定要小心,hash可能会让你陷入尴尬,特别是当你的hash对象特别多时,你就更无法控制了,而且 hash的构造速度较慢。
红黑树并不适应所有应用树的领域。如果数据基本上是静态的,那么让他们待在他们能够插入,并且不影响平衡的地方会具有更好的性能。如果数据完全是静态的,例如,做一个哈希表,性能可能会更好一些。
在实际的系统中,例如,需要使用动态规则的防火墙系统,使用红黑树而不是散列表被实践证明具有更好的伸缩性。Linux内核在管理vm_area_struct时就是采用了红黑树来维护内存块的。
红黑树通过扩展节点域可以在不改变时间复杂度的情况下得到结点的秩。
7.如何扩展红黑树来获得比某个结点小的元素有多少个?
这其实就是求节点元素的顺序统计量,当然任意的顺序统计量都可以需要在O(lgn)时间内确定。
在每个节点添加一个size域,表示以结点 x 为根的子树的结点树的大小,则有
size[x] = size[[left[x]] + size [right[x]] + 1;
这时候红黑树就变成了一棵顺序统计树。
利用size域可以做两件事:
1). 找到树中第i小的结点;
plain
- OS-SELECT(x;,i)
- r = size[left[x]] + 1;
- if i == r
- return x
- elseif i < r
- return OS-SELECT(left[x], i)
- else return OS-SELECT(right[x], i)
思路:size[left[x]]表示在对x为根的子树进行中序遍历时排在x之前的个数,递归调用的深度不会超过O(lgn);
2).确定某个结点之前有多少个结点,也就是我们要解决的问题;
plain
- OS-RANK(T,x)
- r = x.left.size + 1;
- y = x;
- while y != T.root
- if y == y.p.right
- r = r + y.p.left.size +1
- y = y.p
- return r
思路:x的秩可以视为在对树的中序遍历种,排在x之前的结点个数加上一。最坏情况下,OS-RANK运行时间与树高成正比,所以为O (lgn).
8.扩展数据结构有什么步骤?
1).选择基础数据结构;
2).确定要在基础数据结构种添加哪些信息;
3).验证可用基础数据结构上的基本修改操作来维护这些新添加的信息;
4).设计新的操作。
剑指XX游戏(六) - 轻松搞定面试中的红黑树问题的更多相关文章
- 轻松搞定面试中的“虚"
提要 今天要整理的知识点是C++中有关虚的一切. 包括:虚函数,纯虚函数,虚基类,虚继承... 1.什么是虚函数,有什么作用? 在基类用virtual声明成员函数为虚函数.这样就可以在派生类中重新定义 ...
- 轻松搞定面试中的二叉树题目(java&python)
树是一种比较重要的数据结构,尤其是二叉树.二叉树是一种特殊的树,在二叉树中每个节点最多有两个子节点,一般称为左子节点和右子节点(或左孩子和右孩子),并且二叉树的子树有左右之分,其次序不能任意颠倒.二叉 ...
- 面试大总结:Java搞定面试中的链表题目总结
package LinkedListSummary; import java.util.HashMap; import java.util.Stack; /** * http://blog.csdn. ...
- 面试大总结之二:Java搞定面试中的二叉树题目
package BinaryTreeSummary; import java.util.ArrayList; import java.util.Iterator; import java.util.L ...
- (转)面试大总结之一:Java搞定面试中的链表题目
面试大总结之一:Java搞定面试中的链表题目 分类: Algorithm Interview2013-11-16 05:53 11628人阅读 评论(40) 收藏 举报 链表是面试中常出现的一类题目, ...
- 剑指XX(游戏10) - 走正步工厂一个安静的农场游戏的代码
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvc2lsYW5ncXVhbg==/font/5a6L5L2T/fontsize/400/fill/I0JBQk ...
- 三步轻松搞定delphi中CXGRID手动添加复表头(多行表头,报表头)
网上有代码动态生成cxgrid多行表头的源码,地址为:http://mycreature.blog.163.com/blog/static/556317200772524226400/ 如果要手动设计 ...
- Java原来还可以这么学:如何搞定面试中必考的集合类
原创声明 本文作者:黄小斜 转载请务必在文章开头注明出处和作者. 系列文章介绍 本文是<五分钟学Java>系列文章的一篇 本系列文章主要围绕Java程序员必须掌握的核心技能,结合我个人三年 ...
- 轻松搞定项目中的空指针异常Caused by: java.lang.NullPointerException: null
大家在项目测试过程中,是不是经常会碰到这个空指针异常呢Caused by: java.lang.NullPointerException: null 当大家遇到这个问题,大家是怎么处理?自己解决还是让 ...
随机推荐
- c#传入类名添加类对应的表数据
添加方法: public int Insert<T>(T model) where T : class, new() { int sucess = 0; if (model is Temp ...
- 【转】全志A10/A20 Bootloader加载过程分析
原文 : http://blog.csdn.net/allen6268198/article/details/12905425 从这里开始:http://linux-sunxi.org/Bootabl ...
- 《python解释器源码剖析》第4章--python中的list对象
4.0 序 python中的list对象,底层对应的则是PyListObject.如果你熟悉C++,那么会很容易和C++中的list联系起来.但实际上,这个C++中的list大相径庭,反而和STL中的 ...
- SQL语句复习【专题二】
SQL语句复习[专题二] 单行函数(日期.数学.字符串.通用函数.转换函数)多行函数.分组函数.多行数据计算一个结果.一共5个.sum(),avg(),max(),min(),count()分组函数 ...
- python3之POST请求URL
方法一:使用requests模块 import requests as rq import json def funcpost(): url = 'http://www.***.com/' # 需要请 ...
- 4.5. scrapy两大爬虫类_Spider
一:Spider Spider类定义了如何爬取某个(或某些)网站.包括了爬取的动作(例如:是否跟进链接)以及如何从网页的内容中提取结构化数据(爬取item). 换句话说,Spider就是您定义爬取 的 ...
- Access数据库LIKE问题
access里like的通配符用法是这样:“?”表示任何单一字符: “*”表示零个或多个字符: “#”表示任何一个数字 有时候用%作为通配符不行,需要用*号作为通配符select * from tab ...
- MyBatis Demo
什么是 MyBatis? MyBatis 是支持普通 SQL 查询,存储过程和高级映射的优秀持久层框架. MyBatis 消除了几乎所有的 JDBC 代码和参数的手工设置以及对结果集的检索.MyBat ...
- java中创建List<>类型的数组-20171028
遇到了一个问题需要创建List类型的数组,但是在网上查了很多资料,好像发现并不能创建泛型的数组,于是改用Hashmap实现同等的功能. 代码如下: Map<String,List<AddL ...
- 如何判断元素是否在可视区域ViewPort
个性签名: 生如夏花,逝如冬雪:人生如此,何悔何怨. 前言: 经常需要计算元素的大小或者所在页面的位置,offsetWidth,clientWidth,scrollWidth,scrollTop这几个 ...