【问题标题】:Binary Search Tree Insertion method in RubyRuby 中的二叉搜索树插入方法
【发布时间】:2021-10-04 09:13:18
【问题描述】:

我正在研究数据结构,但遇到了一个挑战。目标是根据数组元素的值将数组元素插入二叉搜索树,即(主树的root_node为array[0],左子树的root_node小于父节点,右子树的root_node大于父节点父节点)。这是递归完成的,直到所有数组元素都插入到 BST 中。

我已经实现了两个类:

  1. 表示具有属性(数据、左、右)的节点:
class Node
  attr_reader :data
  attr_accessor :left, :right

  def initialize(data)
    @data = data
  end
end
  1. 表示根值设置为 nil 的二叉搜索树的 BST 类:
class BST
  attr_accessor :root

  def initialize
    @root = nil
  end

  def insert(node)
    insert_node(@root, node)
  end

  def pre_order(node = @root)
    return '' if node.nil?

    print "#{node.data} "
    pre_order(node.left)
    pre_order(node.right)
  end

  private

  def insert_node(node, element)
    if node.nil?
      node = element
    elsif node.data > element.data
      node.left = insert_node(node.left, element)
    else
      node.right = insert_node(node.right, element)
    end

    node
  end
end
  • insert_node 是 BST 的私有方法,它执行将节点插入树的实际工作。我将它与 insert 分开,因为需要使用 RSpec 评估的预期解决方案。
  • 然后我进行了pre_order 遍历,将每个节点打印到终端窗口。
  1. 我有一个binary_search_tree 方法,它接受array 作为输入并在每个数组元素上调用insert 方法。它的主要功能是将数组转换为二叉树,并以pre_order 格式打印出所有树节点。
def binary_search_tree(array)
  tree = BST.new
  array.each { |e| tree.insert(Node.new(e)) }
  tree.pre_order
end

如果我以[8, 3, 10, 1, 6, 14, 4, 7, 13] 作为参数运行binary_search_tree 方法,我希望以# => "8 3 1 6 4 7 10 14 13" 的格式打印出节点,但没有发生任何事情,我不知道我可能哪里出错了。今天我已经在这个挑战上坚持了几个小时,如果有人能提供帮助,那将意义重大。谢谢:)

样本输入:

puts binary_search_tree([8, 3, 10, 1, 6, 14, 4, 7, 13])

预期输出:

8 3 1 6 4 7 10 14 13

得到:

【问题讨论】:

    标签: ruby algorithm data-structures binary-search-tree insertion


    【解决方案1】:

    哦,我终于找到了解决挑战的方法。我只是要演示一下我是如何做到的,以供将来参考:

    因此,我决定摆脱冗余代码并想出一种方法来解决挑战,而不是使用两个单独的方法 insertinsert_helper 节点。这是 BST 类结构:

    class BST
      attr_accessor :root
    
      def initialize
        @root = nil
      end
    
      def insert(node, head = @root)
        return @root = node if @root.nil?
    
        return node if head.nil?
    
        if node.data < head.data
          head.left = insert(node, head.left)
        elsif node.data > head.data
          head.right = insert(node, head.right)
        end
    
        head
      end
    
      def pre_order(node = @root)
        return '' if node.nil?
    
        result = ''
        result += "#{node.data} "
        result += pre_order(node.left)
        result += pre_order(node.right)
      end
    end
    

    insert 方法现在接受两个参数 node 和(head,这是一个可选参数),以允许我们对子树节点执行递归操作并产生所需的结果。

    pre_order 打印每个节点的数据,这是在递归方法中完成的,因此二进制搜索树中的每个节点都以 pre_order 格式打印出来。

    现在如果你调用 BST pre_order 方法,例如:

    def binary_search_tree(array)
      tree = BST.new
      array.each { |e| tree.insert(Node.new(e)) }
      tree.pre_order
    end
    
    puts binary_search_tree([8, 3, 10, 1, 6, 14, 4, 7, 13])
    

    你会得到结果8 3 1 6 4 7 10 14 13。通过更改pre_order 方法,可以打印post_orderinorder 等中的树节点。

    我希望这对其他人有用。编码愉快!

    【讨论】:

      【解决方案2】:
      return '' if node.nil?
      

      这是递归pre_order 的停止条件,也是您从binary_search_tree 返回的内容。您似乎没有任何东西可以将您的树格式化为您想要的形状,"8 3 1 6 4 7 10 14 13"。所以添加该逻辑并在binary_search_tree 方法的末尾调用它。

      【讨论】:

      • 我没有仔细阅读插入代码,我假设它没问题。即使不是,它也与我们在这里遇到的输出不匹配问题无关。
      • 是的,感谢@Sergio Tulentsev 的回复。问题实际上来自 insert_node 方法,它总是为主要 BST root 属性返回 nil,即 tree.root 或者如果您在检查模式下运行代码,您会看到在调用 insert 方法时没有创建任何节点,因此终端上的 nil 值。
      猜你喜欢
      • 2022-01-06
      • 1970-01-01
      • 1970-01-01
      • 2016-01-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多