binary_tree.rb

Heads up: This description was created by AI and might not be 100% accurate.

このRubyスクリプトは、二分探索木(Binary Search Tree)を操作するための機能を提供するものです。

プログラムの特徴:

アルゴリズム:

  1. 二分探索木(BST)の挿入:
    • 与えられたノードがnilの場合、新しいノードを作成し、返します。
    • 挿入する値が現在のノードのアイテムより小さい場合、左の子ノードを再帰的に挿入します。
    • 挿入する値が現在のノードのアイテムより大きい場合、右の子ノードを再帰的に挿入します。
  2. 二分探索木(BST)の削除:
    • 与えられたノードがnilの場合、nilを返します。
    • 挿入する値が現在のノードのアイテムと等しい場合、現在のノードをnilで返します(ノードが削除されることを意味します)。
    • ノードが葉ノードの場合、現在のノードをnilで返します。
    • ノードが2つの子ノードを持つ場合、右子ノードの最小値を調べ、その最小値を持つノードを削除対象のノードの値と交換します。その後、右子ノードから最小値を持つノードを削除します。
  3. ノード最小値検索:
    • ノードの左子ノードがnilになるまで、左子ノードを辿ります。
    • 最後にnilでなくなったノードが、その部分木の最小ノードです。
  4. 二分探索木の構築:
    • 配列の各要素を順番にinsert_node関数を用いて二分探索木に挿入します。
  5. インオーダー走査:
    • 左の子ノードを再帰的に走査します。
    • 現在のノードのアイテムを出力します。
    • 右の子ノードを再帰的に走査します。
  6. インオーダー走査による配列への変換:
    • 左の子ノードを再帰的に走査し、その結果を配列に格納します。
    • 現在のノードのアイテムを配列に追加します。
    • 右の子ノードを再帰的に走査し、その結果を配列に格納します。
    • 最終的に、配列を返します。

Ruby code snippet

# frozen_string_literal: true
#=> nil

class Node
  attr_accessor :item, :left, :right
  def initialize(item)
      @item = item
      @left = nil
      @right = nil
  end
end
#=> :initialize

def insert_node(node, ele)
  return Node.new(ele) if node.nil?

  if ele < node.item
      node.left = insert_node(node.left, ele)
    else
      node.right = insert_node(node.right, ele)
  end
  node
end
#=> :insert_node

def delete_node(node, val)
  return nil if node.nil?

  if val < node.item
      node.left = delete_node(node.left, val)
    elsif val > node.item
      node.right = delete_node(node.right, val)
    else
      return nil if node.left.nil? && node.right.nil?
  
      min_larger_right = find_min(node.right)
      node.item = min_larger_right.item
      node.right = delete_node(node.right, min_larger_right.item)
  end
  node
end
#=> :delete_node

def find_min(node)
  node = node.left while node.left
  node
end
#=> :find_min

def make_binary_tree(data)
  btree = nil
  data.each do |ele|
      btree = insert_node(btree, ele)
  end
  btree
end
#=> :make_binary_tree

def print_with_inorder(btree)
  return if btree.nil?

  print_with_inorder(btree.left)
  puts btree.item
  print_with_inorder(btree.right)
end
#=> :print_with_inorder

def inorder_to_array(btree)
  return [] if btree.nil?

  inorder_to_array(btree.left) + [btree.item] + inorder_to_array(btree.right)
end
#=> :inorder_to_array


data = 3.times.to_a.shuffle
#=> [1, 2, 0]

# make tree
#=> nil
btree = make_binary_tree(data)
#=> 
#<Node:0x00007f15c2d95218


# inorder
#=> nil
p inorder_to_array(btree)
[0, 1, 2]
#=> [0, 1, 2]

# insert
#=> nil
insert_node(btree, 123)
#=> 
#<Node:0x00007f15c2d95218
 @item=1,
 @left=#<Node:0x00007f15c2d950b0 @item=0, @left=nil, @right=nil>,
 @right=
  #<Node:0x00007f15c2d95128
   @item=2,
   @left=nil,
   @right=#<Node:0x00007f15c3234148 @item=123, @left=nil, @right=nil>>>
p inorder_to_array(btree)
[0, 1, 2, 123]
#=> [0, 1, 2, 123]

# delete
#=> nil
delete_node(btree, 0)
#=> 
#<Node:0x00007f15c2d95218
 @item=1,
 @left=nil,
 @right=
  #<Node:0x00007f15c2d95128
   @item=2,
   @left=nil,
   @right=#<Node:0x00007f15c3234148 @item=123, @left=nil, @right=nil>>>
p inorder_to_array(btree)
[1, 2, 123]
#=> [1, 2, 123]

Executed with Ruby 3.4.9.