Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby,这棵二叉树对吗?_Ruby_Binary Search Tree - Fatal编程技术网

Ruby,这棵二叉树对吗?

Ruby,这棵二叉树对吗?,ruby,binary-search-tree,Ruby,Binary Search Tree,因此,我正在进行OdinProject,并从“二进制树”部分开始。我已经编写了一个二叉树,但只用C++使用指针。因此,如果没有指针,我会对节点的连接方式更加困惑: class Node attr_accessor :value, :parent, :left, :right @@nodes = 0 def self.nodes @@nodes end def initialize(value, parent=nil) @value = value

因此,我正在进行OdinProject,并从“二进制树”部分开始。我已经编写了一个二叉树,但只用C++使用指针。因此,如果没有指针,我会对节点的连接方式更加困惑:

class Node

  attr_accessor :value, :parent, :left, :right
  @@nodes = 0

  def self.nodes
    @@nodes
  end

  def initialize(value, parent=nil)
    @value = value
    @parent = parent
    @left = nil
    @right = nil
    @@nodes += 1
  end

end


class BinaryTree

  def initialize
    @root = nil
  end

  def build_tree(arr)
    arr.each {|el| add_child(el,@root)}
    @root
  end

  def add_child(value,node)
    if @root.nil?
      @root = Node.new(value)
    else
      if value < node.value
        node.left.nil? ? node.left = Node.new(value,node) : add_child(value,node.left)
      elsif value > node.value
        node.right.nil? ? node.right = Node.new(value,node) : add_child(value,node.right)
      end
    end
    return node
  end

end
类节点
属性访问器:值,:父对象,:左,:右
@@节点=0
def self.nodes
@@节点
结束
def初始化(值,父项=nil)
@价值=价值
@父=父
@左=零
@右=零
@@节点+=1
结束
结束
类二叉树
def初始化
@根=零
结束
def生成树(arr)
arr.each{| el | add|u child(el,@root)}
@根
结束
def add_子项(值,节点)
如果@root.nil?
@root=Node.new(值)
其他的
如果值node.value
node.right.nil?node.right=node.new(值,节点):添加子项(值,node.right)
结束
结束
返回节点
结束
结束
我已经完成了一些基本的打印功能,它似乎工作正常,但我想知道对于其他更了解ruby的人来说这是否正确。(旁注:我意识到这不会处理重复的数字)。我在树的“建筑”部分遗漏了什么


我担心的原因是看到很多不同的“构建”实现。例如,一个从中点开始的数组,或者这只是用于“排序”数组?

欢迎来到ruby世界!当心,你可能真的很喜欢它,永远不会回到另一种语言:)

以下是我可以给你的一些评论:

测试 当您怀疑代码是否正确时,首先要做的是使用不同的输入测试代码。您可以在控制台中手动完成,也可以编写在开发过程中跟随您的测试

印刷 测试所做工作的一种快速方法是在
节点
类上定义
to_s
方法。例如,这将允许检查您的树是否已排序:

class Node
  …
  def to_s
     "#{left} #{value} #{right}".strip
  end
end 
to_s
是将对象转换为字符串时使用的默认ruby方法。例如,您可以执行以下操作:

#> puts BinaryTree.new.build_tree([5, 9, 1, 6])
1 5 6 9
通过测试 为了让您安心,您可以描述一些测试,这些测试将允许您编写代码、修改代码并检查代码是否仍在工作。我建议使用小型测试,这样做很容易

require 'minitest/autorun'

describe BinaryTree do
  before do
    @constructor = BinaryTree.new
  end

  describe 'when given an array' do
    it 'sorts it' do
      @constructor.build_tree([1, 3, 2]).to_s.must_equal '1 2 3'
    end
  end

  describe 'when given an array with duplicates' do
    it 'builds the correct tree' do
      @constructor.build_tree([1, 3, 2, 3]).to_s.must_equal '1 2 3 3'
    end
  end
end
然后可以使用
ruby-Ilib:testbinary_tree运行它。如果
binary_tree,则rb
是放置代码的文件

您将看到,正如您所提到的,重复的代码不起作用。 您可以通过删除
if…elsif
块中的条件使其工作

然后,您可以编写代码并随时运行测试,这样您就可以确信自己没有破坏任何东西

每次您有一个边缘情况,您不确定您的代码处理,只是把它放在一个测试

计算节点数 如果要计算二叉树中的节点数,则
Node.nodes
方法可能不是您想要的。 它应该在
节点的实例中,而不是在类本身中:如果有多棵树,则每个树都会考虑所有节点

红宝石 您编写的一些内容可以用ruby进行不同的表达:

零是不必要的
attr\u accessor parent

def parent
  @parent
end

def parent=(other)
  @parent = other
end
在ruby中,如果未声明实例变量
@parent
,则默认情况下它的值为
nil
,并且调用
节点。parent
也将返回
nil

初始值设定项中不需要这两行:

@left = nil
@right = nil
不必退货 如果方法中的最后一条指令是return,则不需要
return
关键字。这就是我用上面的
to\s
方法所做的

命名参数 我认为在参数不明显的情况下使用命名参数更干净。 例如,调用
Node.new(value,Node)
实际上无助于理解这两个参数的用途。我知道一个节点应该有一个值,但第二个参数是什么

您可以定义:

def initialize(value, parent: nil)
  # Same as before
end
Node.new(值,父节点)
Node.new(值)

糟糕的事情 将方法移动到它们所属的位置 您的
BinaryTree#add_child
方法应位于节点上。您正在向节点添加一个子节点。将其移到那里,这样就不需要第二个参数:
add\u child(值,node.right)
变成
node.right.add\u child(值)

类节点
...
def add_子项(其他_值)
如果其他_值<值
左。零?self.left=Node.new(其他_值,父项:self):left.add_子项(其他_值)
其他的
对。零?self.right=Node.new(其他值,父项:self):右。添加子项(其他值)
结束
结束
结束
类二叉树
...
def add_子项(值)
如果@root.nil?
@root=Node.new(值)
其他的
@根目录。添加子目录(值)
结束
@根
结束
结束
在那里,您还可以在
BinaryTree
类中摆脱
build_tree
,并将其移动到
节点


我希望它能帮助您完成Ruby之旅。

欢迎来到Ruby世界!当心,你可能真的很喜欢它,永远不会回到另一种语言:)

以下是我可以给你的一些评论:

测试 当您怀疑代码是否正确时,首先要做的是使用不同的输入测试代码。您可以在控制台中手动完成,也可以编写在开发过程中跟随您的测试

印刷 测试所做工作的一种快速方法是在
节点
类上定义
to_s
方法。例如,这将允许检查您的树是否已排序:

class Node
  …
  def to_s
     "#{left} #{value} #{right}".strip
  end
end 
to_s
是将对象转换为字符串时使用的默认ruby方法。例如,您可以执行以下操作:

#> puts BinaryTree.new.build_tree([5, 9, 1, 6])
1 5 6 9
通过测试 为了让您安心,您可以描述一些允许您编写代码的测试,例如