递归顺序遍历二叉搜索树

时间:2016-12-03 05:12:49

标签: recursion rust

我想在二叉搜索树(BST)中实现递归顺序。我使用两个结构构建了一个树:NodeTree。我的代码到目前为止还没有工作,主要是因为Node::inorder中的类型不匹配。

pub struct Node<T> {
    value: T,
    left: Option<Box<Node<T>>>,
    right: Option<Box<Node<T>>>,
}

pub struct Tree<T> {
    root: Option<Box<Node<T>>>,
}

impl<T: Ord> Tree<T> {
    /// Creates an empty tree
    pub fn new() -> Self {
        Tree { root: None }
    }

    pub fn inorder(&self) -> Vec<&T> {
        self.root.as_ref().map(|n| n.inorder()).unwrap() // how to pass result ?
    }
}

impl<T: Ord> Node<T> {
    pub fn inorder(&self) -> Vec<&T> {
        let mut result: Vec<&T> = Vec::new();

        match *self {
            None => return result,

            Some(ref node) => {
                let left_vec = node.left.inorder();
                result.extend(left_vec);
                result.extend(node.value);
                let right_vec = node.right.inorder();
                result.extend(right_vec);
            }
        }
    }
}

这是错误报告:

error[E0308]: mismatched types
  --> src/main.rs:27:13
   |
27 |             None => return result,
   |             ^^^^ expected struct `Node`, found enum `std::option::Option`
   |
   = note: expected type `Node<T>`
   = note:    found type `std::option::Option<_>`

error[E0308]: mismatched types
  --> src/main.rs:29:13
   |
29 |             Some(ref node) => {
   |             ^^^^^^^^^^^^^^ expected struct `Node`, found enum `std::option::Option`
   |
   = note: expected type `Node<T>`
   = note:    found type `std::option::Option<_>`

Node::inorder中,如果节点不存在,我想返回一个空向量;如果节点确实存在,我想要按顺序增长向量并重复。 matchNodeOption之间无效,但我不确定如何在它们之间架起桥梁。

1 个答案:

答案 0 :(得分:4)

Chris Emerson's answer是正确的,但我主张一个更符合内存的版本,它始终附加到同一个向量。这可以防止过度复制值。

impl<T> Tree<T> {
    pub fn inorder(&self) -> Vec<&T> {
        let mut nodes = Vec::new();
        if let Some(ref root) = self.root {
            root.inorder(&mut nodes);
        }
        nodes
    }
}

impl<T: Ord> Node<T> {
    pub fn inorder<'a>(&'a self, result: &mut Vec<&'a T>) {
        if let Some(ref left) = self.left {
            left.inorder(result);
        }
        result.push(&self.value);
        if let Some(ref right) = self.right {
            right.inorder(result);
        }
    }
}

请注意,我已删除: Ord限制,因为遍历不需要。

更好的方法是创建一个遍历遍历的迭代器,然后你可以调用collect