The easy way to implement a Red-Black tree
Red-Black trees are notorious for being nightmares of pointer manipulation. Instructors will show the theory, but won’t torture their students to implement one. Interviewers will avoid asking about it. They probably couldn’t do it themselves.
You should be vaguely familiar with how you might balance a tree. The details, however, are probably unnecessary for the purposes of an interview. – Gayle McDowell, Cracking the coding interview
If you’re proficient in a functional language, you owe it to yourself to implement a Red-Black tree. You’ll be one of the few people that can code a Red-Black tree on a whiteboard.
It will make you realize why people are so excited about the whole functional programming thing.
What is a Red-Black Tree?

A Red-Black tree is a balanced binary search tree. Every node is colored red or black. Three rules hold:
- No red node has a red child.
- Every path from the root to an empty node contains the same number of black nodes.
- An empty node is always black.
Draw a tree with these rules. Notice it’s always relatively-balanced. Try to draw one as unbalanced as possible. You won’t get far.
You can prove the maximum depth of a node is at most 2
Implementation
Let’s implement a set with a Red-Black tree. At minimum we’ll need a member function and an insertfunction.
Data
A tree can be empty, or it can be a node with two subtrees, a color, and an element.
data Tree a = Empty -- Empty does not need a color, it's always black.
| T Color (Tree a) a (Tree a)
data Color = R
| B
Member
The member function searches for an element. It’s a binary search.
member :: Ord a => Tree a -> a -> Bool
member (T _ left e right) x | x == e = True
| x < e = member left x
| x > e = member right x
member Empty _ = False
Insert
The insert function uses the function build, which is a constructor that makes sure the node is balanced.
insert :: Ord a => a -> Tree a -> Tree a
insert x s = let T _ a y b = ins s
in T B a y b
where
ins s'@(T color a' y' b')
| x < y' = build color (ins a') y' b'
| x > y' = build color a' y' (ins b')
| otherwise = s'
ins Empty = T R Empty x Empty
There are four cases when build needs to adjust a node. It detects the case when a black parent has a red child with a red child. It shifts the nodes around to fix it. The solution is the same in every case. (Notice the right hand sides of build are the same).
build :: Color -> Tree a -> a -> Tree a -> Tree a
build B (T R (T R a x b) y c) z d = T R (T B a x b) y (T B c z d)
build B (T R a x (T R b y c)) z d = T R (T B a x b) y (T B c z d)
build B a x (T R (T R b y c) z d) = T R (T B a x b) y (T B c z d)
build B a x (T R b y (T R c z d)) = T R (T B a x b) y (T B c z d)
build color left x right = T color left x right

Afterwards
That’s it. You have a Red-Black tree.
If you want to learn more, read Purely Functional Data Structures by Chris Okasaki. I stole most of my implementation from this book. The build diagram is also from the book.
module RedBlackSet( empty
, member
, insert
) where
data Tree a = Empty
| T Color (Tree a) a (Tree a)
data Color = R
| B
empty :: Ord a => Tree a
empty = Empty
member :: Ord a => Tree a -> a -> Bool
member (T _ left e right) x | x == e = True
| x < e = member left x
| x > e = member right x
member Empty _ = False
insert :: Ord a => a -> Tree a -> Tree a
insert x s = let T _ a y b = ins s
in T B a y b
where
ins s'@(T color a' y' b')
| x < y' = build color (ins a') y' b'
| x > y' = build color a' y' (ins b')
| otherwise = s'
ins Empty = T R Empty x Empty
build :: Color -> Tree a -> a -> Tree a -> Tree a
build B (T R (T R a x b) y c) z d = T R (T B a x b) y (T B c z d)
build B (T R a x (T R b y c)) z d = T R (T B a x b) y (T B c z d)
build B a x (T R (T R b y c) z d) = T R (T B a x b) y (T B c z d)
build B a x (T R b y (T R c z d)) = T R (T B a x b) y (T B c z d)
build color left x right = T color left x right
The easy way to implement a Red-Black tree的更多相关文章
- Red–black tree ---reference wiki
source address:http://en.wikipedia.org/wiki/Red%E2%80%93black_tree A red–black tree is a type of sel ...
- [转载] 红黑树(Red Black Tree)- 对于 JDK TreeMap的实现
转载自http://blog.csdn.net/yangjun2/article/details/6542321 介绍另一种平衡二叉树:红黑树(Red Black Tree),红黑树由Rudolf B ...
- Red Black Tree 红黑树 AVL trees 2-3 trees 2-3-4 trees B-trees Red-black trees Balanced search tree 平衡搜索树
小结: 1.红黑树:典型的用途是实现关联数组 2.旋转 当我们在对红黑树进行插入和删除等操作时,对树做了修改,那么可能会违背红黑树的性质.为了保持红黑树的性质,我们可以通过对树进行旋转,即修改树中某些 ...
- CF1208H Red Blue Tree
CF1208H Red Blue Tree 原本应该放在这里但是这题过于毒瘤..单独开了篇blog 首先考虑如果 $ k $ 无限小,那么显然整个树都是蓝色的.随着 $ k $ 逐渐增大,每个点都会有 ...
- (easy)LeetCode 232.Implement Queue using Stacks
Implement the following operations of a queue using stacks. push(x) -- Push element x to the back of ...
- (easy)LeetCode 225.Implement Stack using Queues
Implement the following operations of a stack using queues. push(x) -- Push element x onto stack. po ...
- 【easy】225. Implement Stack using Queues
用队列实现栈.这个实现方法十分的简单,就是在push这一步的时候直接变成逆序. class MyStack { private: queue<int> q; queue<int> ...
- 2018 ICPC青岛网络赛 B. Red Black Tree(倍增lca好题)
BaoBao has just found a rooted tree with n vertices and (n-1) weighted edges in his backyard. Among ...
- ZOJ - 4048 Red Black Tree (LCA+贪心) The 2018 ACM-ICPC Asia Qingdao Regional Contest, Online
题意:一棵树上有m个红色结点,树的边有权值.q次查询,每次给出k个点,每次查询有且只有一次机会将n个点中任意一个点染红,令k个点中距离红色祖先距离最大的那个点的距离最小化.q次查询相互独立. 分析:数 ...
随机推荐
- 51nod1102(数塔)
题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1002 题意:中文题诶- 思路:简单dp 从底层往上递推,每个 ...
- 关于安装CentOS 7 的注意事项
1.安装VMware Workstation 2.安装CentOS的时候选择GNOME桌面 3.联网设置, VMWare Network Apapter VMnet8 设置IP4 自动获取IP地址,“ ...
- Linux的简单介绍和常用命令的介绍
Linux的简单介绍和常用命令的介绍 本说明以Ubuntu系统为例 Ubuntu系统的安装自行百度,或者参考http://www.cnblogs.com/CoderJYF/p/6091068.html ...
- 浅谈WEB前后端分离
重审业务逻辑 用过MVC的童鞋都知道业务逻辑(Bussiness Logic),但是大多对这概念又是模棱两可,业务逻辑从来都是这样难以理解,谈论前后端分离之前这个概念非常有必要探讨一下! 在简单的CR ...
- IMD中一些JS方法总结
1,日期格式化(如格式成2013-12-27 15:30,new Date().format("yyyy-MM-dd hh:mm:ss"),这种格式在safari浏览器上会出问题, ...
- mysql salve从库设置read only 属性
在MySQL数据库中,在进行数据迁移和从库只读状态设置时,都会涉及到只读状态和Master-slave的设置和关系. 经过实际测试,对于MySQL单实例数据库和master库,如果需要设置为只 ...
- 安装zeppelin
安装zeppelin 1.默认安装好spark集群 2.安装zeppelin 1.解压安装包 tar zxvf zeppelin-0.5.5-incubating-bin-all.tgz 2.配置环境 ...
- 动态更换应用Icon
转:原理1--activity-alias 在AndroidMainifest中,有两个属性: // 决定应用程序最先启动的Activity android.intent.action.MAIN // ...
- Eclipse导入到最新版Android Studio详解
说到使用AndroidStudio,除了新建的项目,我们都会面临的问题是原先Eclipse的代码该怎么导入到AndroidStudio中使用.这方面相关的资料还比较少,自己摸索了一下,总结出这篇博客, ...
- js中的文本编辑器控件KindEditor---那些打酱油的日子
使用文本编辑器控件KindEditor渲染文本域页面显示 this.sync()同步KindEditor的值到textarea文本框 editor.isEmpty()判断文本域是否是空 editer. ...