python 红黑树_手把手教你43行代码写红黑树(包括删除操作)

红黑树是众多平衡二叉搜索树数据结构中比较复杂的一种,而红黑树的删除操作更是出了名的难写。尽管实现复杂,在实际工程中红黑树却有着广泛应用(STL map, Java TreeMap, Linux Kernel),很多教科书(CLRS)中也有所介绍。网上大多数红黑树实现大多很冗长,或者缺少删除操作的实现。本文将用函数时编程语言Haskell,42行代码实现红黑树的插入与删除。阅读本文不需要Haskel...
摘要由CSDN通过智能技术生成

红黑树是众多平衡二叉搜索树数据结构中比较复杂的一种,而红黑树的删除操作更是出了名的难写。

尽管实现复杂,在实际工程中红黑树却有着广泛应用(STL map, Java TreeMap, Linux Kernel),很多教科书(CLRS)中也有所介绍。

网上大多数红黑树实现大多很冗长,或者缺少删除操作的实现。

本文将用函数时编程语言Haskell,42行代码实现红黑树的插入与删除。

阅读本文不需要Haskell与红黑树基础知识,但需要对二叉搜索树算法有基本了解。

对Haskell有基本了解(会写quicksort)的读者可以跳过Haskell 基础。

Haskell 基础

环境

安装ghcThe Glasgow Haskell Compiler​www.haskell.org

Hello world

# a.hs

main = putStrLn "hello world"

运行

$ runghc a.hs

hello world

也有像python一样interactive console

$ ghci

Prelude> putStrLn "hello"

hello

也可以编译成可执行文件

$ ghc a.hs -o a

$ ./a

hello world

List

Prelude> [1,2,3]

[1,2,3]

Prelude> [1..10]

[1,2,3,4,5,6,7,8,9,10]

Haskell的List是单向链表。[1..10]表达式有点像python的range。

head可以获取list的第一个元素,tail函数返回第一个元素之后的list,相当于获得单向链表头节点的value与next

Prelude> head [0..5]

0

Prelude> tail [0..5]

[1,2,3,4,5]

List Comprehension

Haskell List也有类似Python的List Comprehension。Haskell的语法有点像数学里集合的表示。

[x | x

等同于python里的

[x for x in range(10)]

多层循环也可以

[(x,y) | x

相当于Python里

[(x,y) for x in range(4) for y in range(4)]

(Haskell也有类似Python中的Tuple)。

也可以加上条件过滤

[x | x

相当于Python里

[x for x in range(10) if x % 2 == 1]

"++"运算符可以连接两个list

Prelude> [0..2] ++ [3..5]

[0,1,2,3,4,5]

函数与模式匹配(Pattern Matching)

Haskell函数定义与模式匹配密不可分。

阶乘函数在Haskell中可以这么实现:

fact 0 = 1

fact n = n * (fact (n - 1))

函数调用时,参数不需要用括号括起来。

Prelude> fact 3

6

Haskell调用函数时,按顺序尝试匹配定义中的参数。第一个匹配上的参数对应的定义会被采用。

调用fact 3,匹配fact 0失败(3!=0),匹配fact n成功(n可以匹配任何数),于是返回3 * fact 2。

递归调用fact 2,匹配fact 0失败,匹配fact n成功,返回2 * fact 1。

递归调用fact 1,匹配fact 0失败,匹配fact n成功,返回1 * fact 0。

递归调用fact 0,匹配fact 0成功,返回1。

一路回溯到fact 3,最终返回6。

两行顺序不能颠倒,不然"fact n"将匹配任何参数,而"fact 0"永远不会被匹配到。

Haskell自带大整数支持

Prelude> fact 100

93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000

类似的方法可以实现斐波那契数列

fib 0 = 0

fib 1 = 1

fib n = fib (n - 1) + fib (n - 2)

读者可能注意到这个斐波那契数列的实现是

的。下面的方法可以在

时间内计算斐波那契数列

helper 0 a _ = a

helper n a b = helper (n - 1) b (a + b)

fib n = helper n 0 1

第一次接触函数编程的读者可以多花一些时间思考一下。

另外对于快速计算斐波那契数列算法感兴趣的读者可以阅读这篇文章。Fast Fibonacci algorithms​www.nayuki.io

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值