简体   繁体   English

二叉树的 preOrder 和 levelOrder

[英]preOrder and levelOrder for Binary Trees

I'm trying to implement preOrder (First, the root is considered, then recursively the left and then the right subtree) and levelOrder (The nodes are viewed in ascending depth from left to right.)我正在尝试实现 preOrder(首先,考虑根,然后递归地考虑左子树,然后是右子树)和 levelOrder(从左到右按升序查看节点。)

I have:我有:

data BTree a = Nil | Node a (BTree a) (BTree a) deriving Show

preOrder :: BTree a -> [a]
preOrder Nil = []
preOrder (Node x lt rt) = x: ((preOrder lt) ++ (preOrder rt ))

it seems to work, but I'm struggeling with the levelOrder function, I just have:它似乎有效,但我正在努力使用 levelOrder 函数,我只有:

levelOrder :: BTree a -> [a]
levelOrder Nil = []
levelOrder (Node x lt rt) =

I dont know what to do next to make it work.我不知道下一步该怎么做才能让它发挥作用。

Both algorithms require some sort of data structure to store nodes while they wait to be processed.这两种算法都需要某种数据结构来存储等待处理的节点。 preOrder can use the call stack to store the nodes implicitly. preOrder可以使用调用堆栈来隐式存储节点。 levelOrder , however, requires a first-in-first-out queue to be maintained explicitly.然而, levelOrder需要显式维护一个先进先出队列。

Here's an outline of such a queue and the interface it provides.下面是此类队列及其提供的接口的概述。

data Queue a = ...

empty :: Queue a
isEmpty :: Queue a -> Bool
getNext :: Queue a -> (a, Queue a)
append :: Queue a -> a -> Queue a

-- Laws
-- * The empty queue is empty
-- isEmpty empty == True
-- * Appending to a queue produces a non-empty queue
-- isEmpty (append q x) == False
-- * A singleton queue yields the only value and an empty queue
-- getNext (append empty x) == (x, empty)
-- * getNext retrieves from one end, append adds to the other.
-- getNext (append q x) == 
--     let (y, rest) = getNext q 
--     in (y, append rest x)

(For simplicity, getNext is a partial function. You should use isEmpty to avoid trying to get a value from an empty queue. If you like, you can make getNext total by making the signature Queue a -> Maybe (a, Queue a) .) (为简单起见, getNext是一个部分函数。您应该使用isEmpty来避免尝试从空队列中获取值。如果您愿意,可以通过使签名getNext Queue a -> Maybe (a, Queue a) .)


Here is how levelOrder would make use of such a structure: start by putting the root of the tree in the queue, the repeatedly retrieve a value from the queue an process that node.以下是levelOrder如何使用这种结构:首先将树的根放入队列中,然后重复从队列中检索一个值并处理该节点。 The value is added to the return value, while the children are appended to the queue.该值被添加到返回值,而孩子被附加到队列。 Once the q is empty, you're done.一旦 q 为空,你就完成了。

levelOrder :: BTree a -> [a]
levelOrder tree = go (append empty tree)
  where go q | isEmpty q = []
        go q = let (next, rest) = getNext q
               in case next of
                    Nil -> ...
                    (Node x left right) -> ...

I leave it to you to define the Queue data type, the functions that operate on that type, and to finish the definition of levelOrder using the queue.我留给您定义Queue数据类型、操作该类型的函数,并使用队列完成levelOrder的定义。

(Once you've defined the data type, you may want to skip some of the interface functions in favor of direct pattern matching. For example, if you end up with a dedicated data constructor for an empty Queue , you don't really need isEmpty , or at least its definition is trivial.) (一旦定义了数据类型,您可能希望跳过一些接口函数以支持直接模式匹配。例如,如果您最终得到一个用于空Queue的专用数据构造函数,您实际上并不需要isEmpty ,或者至少它的定义是微不足道的。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM