红黑树:
红黑树的5个特性:
性质1. 节点是红色或黑色。
性质2. 根是黑色。
性质3. 所有叶子都是黑色(叶子是NULL节点)。
性质4. 每个红色节点的两个子节点都是黑色。(从每个叶子到根的所有路径上不能有两个连续的红色节点)
性质5. 从任一节点到其每个叶子的所有简单路径 都包含相同数目的黑色节点。
插入的情况:
若是根节点直接插入.
若父亲是黑色那么直接插入.
若父亲是红色那么祖父必定是黑色,这种情况下看叔叔,如果叔叔是红色那么把祖父改成红色,父亲改成黑色,叔叔改成黑色就好了.如果叔叔是黑色,那么通过旋转操作来调整.
删除的话情况太复杂了,不好总结,贴上另一篇博客:https://www.cnblogs.com/tongy0/p/5460623.html
hash表
就是通过一个hash函数,h(key)映射到一个value值,然后把key存到该value值的数组里,查询的时候同样通过hash函数计算出value值,直接访问该数组就可以O(1)查询,但是这样的话可能不同的key会计算到同一个value,毕竟是多数映射到少数值,所以就要解决冲突问题,解决冲突的话典型有两种方法。
1.开放地址法
就是如果产生冲突了,那么从该位置往下遍历,直到找到空位为止,找到空位就把该key放上去。这个方法很不好,假设你冲突了,往下搜,那么其他值的冲突也会影响到你遍历的速度,插入和删除复杂度会增加很多。不建议使用。
2.链地址法
就是建链表数组,每次都在相应的value链表的最后插入,这样的话不同的value的冲突不会相互影响,STL的hashtable就是这样实现的,还有更快的实现方法就是当链表扩展到一定的程度之后改用红黑树实现,这样在数据量非常大的时候能更进一步优化,据我所知STL的hashmap是这样实现的。