haskell实现快排的代码为什么这么短

1 篇文章 0 订阅
1 篇文章 0 订阅
    如果在某度百科上看过快排词条,同时用自己擅长的语言写过快排的同学,看到词条后面用不同语言实现快排的时候肯定看过haskell的这段快排代码:
q_sort n=case n of
    []->[]
    (x:xs)->q_sort [a|a<-xs,a<=x]++[x]++q_sort [a|a<-xs,a>x]
    what!就这?居然实现了面试官随时可能给你扔过来的“同学,请写一个快排吧”这个问题;你不会在骗我吧。然而并没有,它的确能运行呢,货真价实的快排!

    为什么它能够实现快排呢?首先回到问题根源:快排是什么,用最通俗的话说,快排就是从一堆数里面取一个数a(任意或者按照一定规则取出的一个数,不要在意这些细节),然后把小于它的扔它左边,大于它的扔它右边,三者组合在一起后,对左右的两堆数执行同样的操作,直到不能再分就结束,以空间换时间,最终实现快速排序的目的。

    抛开haskell语法,解释一下上面一段代码到底在是个什么逻辑呢?
q_sort n=case n of    
 //q_sort ->函数名 
 //n->形参 
 //case->暂时可以理解为其类似他语言的分支语句
    []->[] //如果传递的为空,则返回空
    (x:xs)->q_sort [a|a<-xs,a<=x]++[x]++q_sort [a|a<-xs,a>x]
    //这个分支表示不为空的情况
    //(x:xs)-->把传递的数组结构分成首项+剩余两个部分 同时作为参数传递到后面的函数中,首项的作用就是上面说的a啦,当然也可以时最后一项,这里取首项时方便一些
    //[a|a<-xs,a<=x] 这里是什么意思呢?a|,这个a代表输出,可以理解为返回值,a<-xs,a<=x表示这个a从xs中来,同时a小于x,也就是传进来的去掉第一项的数组,输出小于等于x的数组元素,综合来看,这句话实现了:把小的数组元素扔左边的功能;

    //++是拼接的意思
    //
    //[a|a<-xs,a>x]同左边操作类似,返回大于x的所有数组元素
    //q_sort然后再分别对左右进行快排

    是不是有种无语的感觉,这不就是把快排的思路用函数的方式写出来么,的确是这样啊。代码精简,逻辑清晰,关注是什么,而不是实现的细节!
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
平衡二叉树(Balanced Binary Tree)又称为 AVL 树,它是一种自平衡二叉查找树。它的性质是:任何一个节点的左子树和右子树的高度差都不超过 1。 下面是 Haskell 实现平衡二叉树的代码: ``` data Tree a = Leaf | Node (Tree a) a (Tree a) deriving (Show) -- 计算树的高度 height :: Tree a -> Int height Leaf = 0 height (Node l _ r) = 1 + max (height l) (height r) -- 右旋 rightRotate :: Tree a -> Tree a rightRotate (Node (Node a x b) y c) = Node a x (Node b y c) rightRotate t = t -- 左旋 leftRotate :: Tree a -> Tree a leftRotate (Node a x (Node b y c)) = Node (Node a x b) y c leftRotate t = t -- 插入 insert :: (Ord a) => a -> Tree a -> Tree a insert x Leaf = Node Leaf x Leaf insert x (Node l y r) | x < y = balance (Node (insert x l) y r) | x > y = balance (Node l y (insert x r)) | otherwise = Node l y r -- 平衡因子 balanceFactor :: Tree a -> Int balanceFactor Leaf = 0 balanceFactor (Node l _ r) = height l - height r -- 平衡 balance :: Tree a -> Tree a balance t | bf > 1 && x < y = rightRotate t | bf < -1 && x > y = leftRotate t | bf > 1 && x > y = leftRotate (rightRotate t) | bf < -1 && x < y = rightRotate (leftRotate t) | otherwise = t where bf = balanceFactor t x = value t y = value (leftChild t) -- 左子节点 leftChild :: Tree a -> Tree a leftChild (Node l _ _) = l -- 右子节点 rightChild :: Tree a -> Tree a rightChild (Node _ _ r) = r -- 节点的值 value :: Tree a -> a value (Node _ x _) = x -- 创建平衡二叉树 create :: (Ord a) => [a] -> Tree a create = foldl (flip insert) Leaf ``` 使用方法: ``` main = do let t = create [3, 2, 1, 4, 5] print t ``` 输
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值