数据结构面试总结

B树和B+树的区别

http://www.cnblogs.com/vincently/p/4526560.html

B和B+树的区别在于,B+树的非叶子结点只包含导航信息,不包含实际的值,所有的叶子结点和相连的节点使用链表相连,便于区间查找和遍历。

B+ 树的优点在于:
•由于B+树在内部节点上不包含数据信息,因此在内存页中能够存放更多的key。 数据存放的更加紧密,具有更好的空间局部性。因此访问叶子节点上关联的数据也具有更好的缓存命中率。
•B+树的叶子结点都是相链的,因此对整棵树的便利只需要一次线性遍历叶子结点即可。而且由于数据顺序排列并且相连,所以便于区间查找和搜索。而B树则需要进行每一层的递归遍历。相邻的元素可能在内存中不相邻,所以缓存命中性没有B+树好。

但是B树也有优点,其优点在于,由于B树的每一个节点都包含key和value,因此经常访问的元素可能离根节点更近,因此访问也更迅速。

B树和B+广泛应用于文件存储系统以及数据库系统中

AVL树与红黑树

AVL树本质上还是一棵二叉搜索树(因此读者可以看到我后面的代码是继承自二叉搜索树的),它的特点是:
1. 本身首先是一棵二叉搜索树。
2. 带有平衡条件:每个结点的左右子树的高度之差的绝对值(平衡因子)最多为1。

红黑树并不追求“完全平衡”——它只要求部分地达到平衡要求,降低了对旋转的要求,从而提高了性能。

红黑树能够以O(log2 n) 的时间复杂度进行搜索、插入、删除操作。此外,由于它的设计,任何不平衡都会在三次旋转之内解决。当然,还有一些更好的,但实现起来更复杂的数据结构 能够做到一步旋转之内达到平衡,但红黑树能够给我们一个比较“便宜”的解决方案。红黑树的算法时间复杂度和AVL相同,但统计性能比AVL树更高。

如果数据完全是静态的,例如,做一个哈希表,性能可能会更好一些

典型的用途是实现关联数组

比较

AVL是一种高度平衡的二叉树,所以通常的结果是,维护这种高度平衡所付出的代价比从中获得的效率收益还大,故而实际的应用不多,更多的地方是用追求局部而不是非常严格整体平衡的红黑树。当然,如果场景中对插入删除不频繁,只是对查找特别有要求,AVL还是优于红黑的。

红黑树的应用就很多了
- 著名的linux进程调度Completely Fair Scheduler,用红黑树管理进程控制块
- epoll在内核中的实现,用红黑树管理事件块
- nginx中,用红黑树管理timer等
- Java的TreeMap实现

B和B+主要用在文件系统以及数据库中做索引等,磁盘文件组织

trie 树的一个典型应用是前缀匹配

TreeTable

Collections.sort的原理

Object[] a = list.toArray();
        Arrays.sort(a);
        ListIterator<T> i = list.listIterator();
        for (int j=0; j<a.length; j++) {
            i.next();
            i.set((T)a[j]);
        }

我有看过JDK1.7版本的,Collections.sort和Arrays.sort

排序Object用Timsort以前是MergeSort,排序基本类型用快排

据说1.6是 MergeSort,1.7改为了 Timsort
也可以用户选择为 MergeSort

Timsort小于32,使用BinarySort二分查找的方法将后续的数插入之前的已排序数组
大于32使用

Timsort是结合了合并排序(merge sort)和插入排序(insertion sort)而得出的排序算法

Timsort的核心过程

TimSort 算法为了减少对升序部分的回溯和对降序部分的性能倒退,将输入按其升序和降序特点进行了分区。排序的输入的单位不是一个个单独的数字,而是一个个的块-分区。其中每一个分区叫一个run。针对这些 run 序列,每次拿一个 run 出来按规则进行合并。每次合并会将两个 run合并成一个 run。合并的结果保存到栈中。合并直到消耗掉所有的 run,这时将栈上剩余的 run合并到只剩一个 run 为止。这时这个仅剩的 run 便是排好序的结果。

可以说是归并排序的改进

https://www.coder4.com/archives/4092

4.3) 开始真正的TimSort过程:

4.3.1) 选取minRun大小,之后待排序数组将被分成以minRun大小为区块的一块块子数组

a) 如果数组大小为2的N次幂,则返回16(MIN_MERGE / 2)
b) 其他情况下,逐位向右位移(即除以2),直到找到介于16和32间的一个数image2

4.3.2) 类似于4.2.a找到初始的一组升序数列
4.3.3) 若这组区块大小小于minRun,则将后续的数补足(采用binary sort插入这个数组)
4.3.4) 为后续merge各区块作准备:记录当前已排序的各区块的大小
4.3.5) 对当前的各区块进行merge,merge会满足以下原则(假设X,Y,Z为相邻的三个区块):

a) 只对相邻的区块merge
b) 若当前区块数仅为2,If X<=Y,将X和Y merge
b) 若当前区块数>=3,If X<=Y+Z,将X和Y merge,直到同时满足X>Y+Z和Y>Z
image3

4.3.6) 重复4.3.2 ~ 4.3.5,直到将待排序数组排序完
4.3.7) Final Merge:如果此时还有区块未merge,则合并它们

image4

二叉平衡树删除节点

如果要删除的节点为叶子节点,就找到了要删除的节点

如果要删除的节点为只有一棵子树的节点就找到了要删除的节点

用A的左子树最大数据或右子树最小数据(假设B节点)代替A节点的数据

分布式锁

分布式锁是控制分布式系统之间同步访问共享资源的一种方式。

image

基于zookeeper瞬时有序节点实现的分布式锁,其主要逻辑如下(该图来自于IBM网站)。大致思想即为:每个客户端对某个功能加锁时,在zookeeper上的与该功能对应的指定节点的目录下,生成一个唯一的瞬时有序节点。判断是否获取锁的方式很简单,只需要判断有序节点中序号最小的一个。当释放锁的时候,只需将这个瞬时节点删除即可。同时,其可以避免服务宕机导致的锁无法释放,而产生的死锁问题。

http://surlymo.iteye.com/blog/2082684

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值