泛函编程(8)-数据结构-Tree

    上节介绍了泛函数据结构List及相关的泛函编程函数设计使用,还附带了少许多态类型(Polymorphic Type)及变形(Type Variance)的介绍。有关Polymorphism的详细介绍会放在typeclass讨论中。为了更多了解泛函数据结构(Functional Data Structure),想在这个章节把另一个我们熟悉的数据结构-Tree做些简单介绍。

    Tree的状态不是枝(Branch)就是叶(Leaf),这个很容易理解。那么就按照上节设计List那样设计Tree类型:

  trait Tree[+A] 
  case class Leaf[A](value: A) extends Tree[A]
  case class Branch[A](left: Tree[A], right: Tree[A]) extends Tree[A]


类参数+A代表协变(covariant),这个在上节List中已经介绍过了。先创建一个Tree实例(Tree Instance):

  val tree = Branch(Branch(Leaf(1),Leaf(2)),Branch(Branch(Leaf(10),Leaf(8)),Leaf(3)))
                                                  //> tree  : ch3.tree.Branch[Int] = Branch(Branch(Leaf(1),Leaf(2)),Branch(Branch(
                                                  //| Leaf(10),Leaf(8)),Leaf(3)))

创建了一个Tree Instance tree,如下图:


数数有几个节点:

  	def size: Int = this match {
  		case Leaf(_) => 1
  		case Branch(l,r) => 1 + l.size + r.size
  	}
  tree size                                       //> res0: Int = 9

这是所有branch + leaf 总数。

分开计算branch 和 leaf 数量:

  	def countLeafs: Int = this match {
  		case Leaf(_) => 1
  		case Branch(l,r) => 0 + l.size + r.size
  	}
   	def countBranches: Int = this match {
  		case Leaf(_) => 0
  		case Branch(l,r) => 1 + l.size + r.size
  	}
  tree.countLeafs                                 //> res1: Int = 8
  tree.countBranches                              //> res2: Int = 9

探探最深有多深:

  	def depth: Int = this match {
  		case Leaf(_) => 0
  		case Branch(l,r) => 1 + (l.depth max r.depth)
  	}
  tree depth                                      //> res1: Int = 3

找出最大值的Leaf:

  	def maxValue: Int = this match {
  		case Leaf(a: Int) => a
  		case Branch(l,r) => l.maxValue max r.maxValue
  	}
  tree maxValue                                   //> res2: Int = 10


可以从以上这些函数得出一下共性。把共性抽象出来用fold来实现:

		def fold[B](f: A => B)(g: (B,B) => B): B = this match {
			case Leaf(n) => f(n)
			case Branch(l,r) => g(l.fold(f)(g), r.fold(f)(g))
		}

函数fold分别收到两个方法f,g:f用来处理Leaf,g用来处理Branch。看看用fold来实现上面的函数:

		def sizeByfold = fold(a => 1)(1 + _ + _)
		def maxValueByfold(l: Tree[Int]) = l.fold(a => a)((x,y) => 0 + (x max y))
		def depthByfold = fold(a => 0)((x,y) => 1 + (x max y))
  tree sizeByfold                                 //> res3: Int = 9
  
  tree depthByfold                                //> res4: Int = 3
  
  tree.maxValueByfold(tree)                       //> res5: Int = 10


可能这个 tree.maxValueByfold(tree) 有点怪,但如果把函数实现放到 object Tree里然后import Tree._就可以了。

下面把map和flatMap实现了:

  	def map[B](f: A => B): Tree[B] = this match {
  		case Leaf(a) => Leaf(f(a))
  		case Branch(l,r) => Branch(l.map(f),r.map(f))
  	}
  	def flatMap[B](f: A => Tree[B]): Tree[B] = this match {
  		case Leaf(a) => f(a)
  		case Branch(l,r) => Branch(l.flatMap(f), r.flatMap(f))
  	}





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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值