在Ruby中实现二叉树
我一直在尝试在Ruby中实现BinaryTree类,但我发现在Ruby中实现二叉树,ruby,binary-tree,stack-overflow,Ruby,Binary Tree,Stack Overflow,我一直在尝试在Ruby中实现BinaryTree类,但我发现堆栈级别太深了错误,尽管我似乎没有在特定的代码段中使用任何递归: 1. class BinaryTree 2. include Enumerable 3. 4. attr_accessor :value 5. 6. def initialize( value = nil ) 7. @value = value 8. @left = BinaryTre
堆栈级别太深了
错误,尽管我似乎没有在特定的代码段中使用任何递归:
1. class BinaryTree
2. include Enumerable
3.
4. attr_accessor :value
5.
6. def initialize( value = nil )
7. @value = value
8. @left = BinaryTree.new # stack level too deep here
9. @right = BinaryTree.new # and here
10. end
11.
12. def empty?
13. ( self.value == nil ) ? true : false
14. end
15.
16. def <<( value )
17. return self.value = value if self.empty?
18.
19. test = self.value <=> value
20. case test
21. when -1, 0
22. self.right << value
23. when 1
24. self.left << value
25. end
26. end # <<
27.
28. end
然后是
虽然我似乎没有在这段代码中使用任何递归:
1. class BinaryTree
2. include Enumerable
3.
4. attr_accessor :value
5.
6. def initialize( value = nil )
7. @value = value
8. @left = BinaryTree.new # stack level too deep here
9. @right = BinaryTree.new # and here
10. end
11.
12. def empty?
13. ( self.value == nil ) ? true : false
14. end
15.
16. def <<( value )
17. return self.value = value if self.empty?
18.
19. test = self.value <=> value
20. case test
21. when -1, 0
22. self.right << value
23. when 1
24. self.left << value
25. end
26. end # <<
27.
28. end
然而
def initialize( value = nil )
@value = value
@left = BinaryTree.new # this calls initialize again
@right = BinaryTree.new # and so does this, but you never get there
end
这就是无限递归。您调用initilize
,后者依次调用new
,后者依次调用initialize
。。。我们四处走走
您需要在其中添加一个保护,以检测您已经初始化了主节点,现在正在初始化leafs,在这种情况下,@left
和@right
应该设置为nil
def initialize( value=nil, is_sub_node=false )
@value = value
@left = is_sub_node ? nil : BinaryTree.new(nil, true)
@right = is_sub_node ? nil : BinaryTree.new(nil, true)
end
不过说实话。。。为什么不从一开始就将left和right初始化为nil呢?他们还没有价值观,所以你得到了什么?它在语义上更有意义;创建一个包含一个元素的新列表,即左元素和右元素都不存在。我只想使用:
def initialize(value=nil)
@value = value
@left = @right = nil
end
1。类二叉树
2.包括可枚举的
3.
4.属性存取器:值
5.
6.def初始化(值=零)
7. @价值=价值
8.结束
9
10定义每次访问
11如果self.nil返回?
12
13屈服自我价值
14self.left.如果self.left,则每个(&block)
15self.right.如果self.right,则每个(&block)
16结束
17
18def是空的吗?
19. # 代码在这里
20结束
21
22def您可能需要修复代码中的无限递归。下面是一个二叉树的工作示例。您需要有一个基本条件来在某个地方终止递归,否则它将是一个无限深的堆栈
# Example of Self-Referential Data Structures - A Binary Tree
class TreeNode
attr_accessor :value, :left, :right
# The Tree node contains a value, and a pointer to two children - left and right
# Values lesser than this node will be inserted on its left
# Values greater than it will be inserted on its right
def initialize val,left,right
@value = val
@left = left
@right = right
end
end
class BinarySearchTree
# Initialize the Root Node
def initialize val
puts "Initializing with: " + val.to_s
@root = TreeNode.new(val,nil,nil)
end
# Pre-Order Traversal
def preOrderTraversal(node= @root)
return if (node == nil)
preOrderTraversal(node.left)
preOrderTraversal(node.right)
puts node.value.to_s
end
# Post-Order Traversal
def postOrderTraversal(node = @root)
return if (node == nil)
puts node.value.to_s
postOrderTraversal(node.left)
postOrderTraversal(node.right)
end
# In-Order Traversal : Displays the final output in sorted order
# Display smaller children first (by going left)
# Then display the value in the current node
# Then display the larger children on the right
def inOrderTraversal(node = @root)
return if (node == nil)
inOrderTraversal(node.left)
puts node.value.to_s
inOrderTraversal(node.right)
end
# Inserting a value
# When value > current node, go towards the right
# when value < current node, go towards the left
# when you hit a nil node, it means, the new node should be created there
# Duplicate values are not inserted in the tree
def insert(value)
puts "Inserting :" + value.to_s
current_node = @root
while nil != current_node
if (value < current_node.value) && (current_node.left == nil)
current_node.left = TreeNode.new(value,nil,nil)
elsif (value > current_node.value) && (current_node.right == nil)
current_node.right = TreeNode.new(value,nil,nil)
elsif (value < current_node.value)
current_node = current_node.left
elsif (value > current_node.value)
current_node = current_node.right
else
return
end
end
end
end
bst = BinarySearchTree.new(10)
bst.insert(11)
bst.insert(9)
bst.insert(5)
bst.insert(7)
bst.insert(18)
bst.insert(17)
# Demonstrating Different Kinds of Traversals
puts "In-Order Traversal:"
bst.inOrderTraversal
puts "Pre-Order Traversal:"
bst.preOrderTraversal
puts "Post-Order Traversal:"
bst.postOrderTraversal
=begin
Output :
Initializing with: 10
Inserting :11
Inserting :9
Inserting :5
Inserting :7
Inserting :18
Inserting :17
In-Order Traversal:
5
7
9
10
11
17
18
Pre-Order Traversal:
7
5
9
17
18
11
10
Post-Order Traversal:
10
9
5
7
11
18
17
=end
自引用数据结构示例-二叉树
三烯类
属性访问器:值,:左,:右
#树节点包含一个值和一个指向两个子节点(左和右)的指针
#小于此节点的值将插入其左侧
#将在其右侧插入大于该值的值
def初始化val,左,右
@值=val
@左=左
@右=右
结束
结束
类二进制搜索树
#初始化根节点
def初始化val
将“初始化为:”+val.to_s
@root=TreeNode.new(val,nil,nil)
结束
#预序遍历
def preOrderTraversal(节点=@root)
如果(节点==nil)返回
预订单行程(节点左)
预订单行程(右节点)
将node.value.to_
结束
#后序遍历
def postOrderTraversal(节点=@root)
如果(节点==nil)返回
将node.value.to_
postOrderTraversal(node.left)
postOrderTraversal(node.right)
结束
#按顺序遍历:按排序顺序显示最终输出
#先显示较小的孩子(向左)
#然后在当前节点中显示该值
#然后在右侧显示较大的子对象
def inOrderTraversal(节点=@root)
如果(节点==nil)返回
inOrderTraversal(node.left)
将node.value.to_
inOrderTraversal(node.right)
结束
#插入值
#当值>当前节点时,向右移动
#当值<当前节点时,向左移动
#当您点击一个nil节点时,这意味着应该在那里创建新节点
#不会在树中插入重复的值
def插入(值)
将“插入:”+值添加到
当前_节点=@root
而零!=当前节点
如果(值current\u node.value)&&(current\u node.right==nil)
当前_node.right=TreeNode.new(值,nil,nil)
elsif(值<当前节点值)
当前节点=当前节点。左
elsif(值>当前节点值)
当前节点=当前节点。右
其他的
返回
结束
结束
结束
结束
bst=BinarySearchTree.new(10)
bst.insert(11)
bst.insert(9)
bst.insert(5)
bst.insert(7)
bst.insert(18)
bst.insert(17)
#演示不同类型的遍历
将“按顺序遍历:”
bst.inOrderTraversal
放置“预顺序遍历:”
bst.preOrderTraversal
放置“后序遍历:”
bst.postOrderTraversal
开始
输出:
初始化时间:10
插入:11
插入:9
插入:5
插入:7
插入:18
插入:17
按顺序遍历:
5.
7.
9
10
11
17
18
预顺序遍历:
7.
5.
9
17
18
11
10
后序遍历:
10
9
5.
7.
11
18
17
=结束
Ref:@pranshantb1984-您给出的Ref很好,但我认为代码中有一个小改动。需要更新订单前和订单后代码,如下所示
# Post-Order Traversal
def postOrderTraversal(node= @root)
return if (node == nil)
postOrderTraversal(node.left)
postOrderTraversal(node.right)
puts node.value.to_s
end
# Pre-Order Traversal
def preOrderTraversal(node = @root)
return if (node == nil)
puts node.value.to_s
preOrderTraversal(node.left)
preOrderTraversal(node.right)
end
预顺序遍历
10->9->5->7->11->18->17
后序遍历
7->5->9->17->18->11->10我想再问一个问题。这是初始化属性的标准方法吗?这些属性属于它们出现的类的类型?我不确定我问的方法是否正确。@Maputo:是的,你定义了一个名为initialize
的方法,当有人调用YourType.new
时就会调用这个方法。你应该把左和右设置为零。这更有意义,它解决了无限递归问题。如果我这样做,我得到的是@Maputo的其他问题:好的,那么你的代码中有另一个错误,这并不意味着你最初的方法是正确的。您永远不会分配值
,只需一次又一次地递归调用该方法即可。如果要使用递归,则需要一个保护程序来确定何时停止,即何时分配值
并退出该过程。@Maputo:将它们初始化为nil
。变量不是在Ruby中键入的,而是值
# Post-Order Traversal
def postOrderTraversal(node= @root)
return if (node == nil)
postOrderTraversal(node.left)
postOrderTraversal(node.right)
puts node.value.to_s
end
# Pre-Order Traversal
def preOrderTraversal(node = @root)
return if (node == nil)
puts node.value.to_s
preOrderTraversal(node.left)
preOrderTraversal(node.right)
end