2017-01-05 7 views
1

ヒープを構築するとき(配列を使わないでチャレンジ)、誰かが助けることができるかどうか疑問に思っています。私がこれまで行ってきたところでは、いくつかのビルドされたノードを挿入することができ、ヒープ構造は出力から正しく構築されます。しかし、特定のノード#findに行くと、私のノードが出力されたツリーと一致しないように見えるので、nilを受け取る。私ができるように凝縮としてそれを維持する、ここで私が持っているものです。Rubyバイナリヒープ挿入とジレンマの発見

ノードコンストラクタ& HeapTree #insert方法

class Node 
    attr_accessor :title 
    attr_accessor :rating 
    attr_accessor :parent 
    attr_accessor :left 
    attr_accessor :right 

    def initialize(title, rating) 
    @title = title 
    @rating = rating 
    @parent = nil 
    @left = nil 
    @right = nil 
    end 
end 

class HeapSearchTree 

    def initialize 
    @root = nil 
    @heapsize = 1 
    end 

    def insert(node) 
    return nil if node.nil? 

    if @root.nil? 
     @root = node 
    else 
     current = @root 
     @heapsize += 1 #every insert increases heapsize; used for balancing heap 
     until current.left.nil? || current.right.nil? 
     if @heapsize % 2 == 0 
      current = current.left 
     else 
      current = current.right 
     end 
     end 

     #after figuring out to go left or right, find the first nil spot 
     if current.left.nil? && current.right.nil? 
     current.left = node 
     node.parent = current 
     elsif current.left.nil? && !current.right.nil? 
     current.left = node 
     node.parent = current 
     elsif !current.left.nil? && current.right.nil? 
     current.right = node 
     node.parent = current 
     end 

     #heapify by swapping titles and ratings because if I swap parent node for higher node it doesnt stick. 
     while node.rating >= node.parent.rating 
     if node.parent.rating <= node.parent.left.rating 
      temp_title = node.parent.title 
      temp_rating = node.parent.rating 

      node.parent.title = node.parent.left.title 
      node.parent.rating = node.parent.left.rating 
      node.parent.left.title = temp_title 
      node.parent.left.rating = temp_rating 
     elsif node.parent.rating <= node.parent.right.rating 
      temp_title = node.parent.title 
      temp_rating = node.parent.rating 

      node.parent.title = node.parent.right.title 
      node.parent.rating = node.parent.right.rating 
      node.parent.right.title = temp_title 
      node.parent.right.rating = temp_rating 
     end 
     end 
    end 
    end 
    def find([email protected], movie_title) 
    if root.title == movie_title 
     puts "END OF RECURSION" 
     puts "movie_title entered: #{movie_title}" 
     puts "root.title: #{root.title}" 
     return root 
    else 
     loop = 0 
     left = find(root.left, title) if root.left 
     right = find(root.right, title) if root.right 
     left || right 
     loop += 1 
     puts loop 
    end 
    end 

問題の写真

あなたは、martianを挿入することでわかりますツリーは適切に再配置されます。しかし、私がtree.find(matrix.title)になると、それはmartian.titleとして渡され、リターンとしてゼロになる。

enter image description here

私はしばらくの間、これで困惑してきたし、私を助けるためにウェブ経由で何かを見つけることができません。 node.parentのレーティングがnodeに満たない場合は、node.parentでタイトルとレーティングを交換しています。 node IDはではなく、であり、情報のみです。この仕事をするための解決策を探しています。ほとんどの場合、ビルドされた配列が表示されますが、私は学習目的で配列を使用したくありません。おかげ

ノート

私は#insertから湧き上がっしばらくループから私のプログラムブレークを見つけました。私は現在、nodenode.parentを動かそうとしていますが、それほど難しいと証明しています。

+0

を再作成することによって、私の問題を解決しました-オフ? – Coolness

+0

'@ heapsize'が変更されています。私の問題はタイトルと評価を並べ替えるときに '#insert'の中にあります。残念ながら、何とか私のオブジェクトデータを変更します。 'martian'を挿入した後に' matrix.title'を置くと 'matrix.title = martian.title'となります。 – DustinRW

+0

ビルドしているのは、ある種のバイナリツリーですが、私が知っていることは確かに[ヒープ](https://en.wikipedia.org/wiki/Heap_(data_structure))ではありません。間違いなく[バイナリヒープ](https://en.wikipedia.org/wiki/Binary_heap)です。さらに、ヒープは、ツリーの網羅的な検索を行う必要があるため、検索のための特に優れたデータ構造ではありません。この "ヒープ"で解決しようとしている問題は何ですか? –

答えて

0

は私が気づくことの一つは、あなたが最初のノードを追加しているとき、あなたは `@のheapsize`が増加していないので、あなたのサイズが1であるように思わということです#insert

def insert(root, node) 
    root = @root 
    current = @root 
    @heapsize += 1 #every insert increases heapsize; used for balancing heap 

    until current.left.nil? || current.right.nil? 
     if @heapsize % 2 == 0 
     current = current.left 
     else 
     current = current.right 
     end 
    end 

    if current.left.nil? && current.right.nil? 
     current.left = node 
     node.parent = current 
    elsif current.left.nil? && !current.right.nil? 
     current.left = node 
     node.parent = current 
    elsif !current.left.nil? && current.right.nil? 
     current.right = node 
     node.parent = current 
    end 

    #if rating > (greater than) its parents rating 
    while node.rating >= node.parent.rating 
     loop = 1 
     temp_parent = node.parent 
     temp_parent_right = node.parent.right 
     temp_parent_left = node.parent.left 
     temp_node_left = node.left 
     temp_node_right = node.right 
    # if node is greater then its parent and node is to the left of parent 
     if node.parent.parent.nil? && node == node.parent.left 
     puts "im here on left and parents parent is nil" 
     node.right = node.parent.right 
     node.parent = node.parent.parent 
     node.left = temp_parent 

     node.left.parent = node 
     node.left.left = temp_node_left 
     node.left.right = temp_node_right 

     if !node.right.nil? 
      node.right.parent = node 
     end 

     @root = node 
     break 
    # if node is greater then its parent and node is to the right of parent 
     elsif node.parent.parent.nil? && node == node.parent.right 
     puts "im here on right and parents parent is nil" 

     node.left = node.parent.left 
     node.parent = node.parent.parent 
     node.right = temp_parent 

     node.right.parent = node 
     node.right.right = temp_node_right 
     node.right.left = temp_node_left 
     node.left.parent = node 

     @root = node 
     break 


     elsif !node.parent.nil? && node == node.parent.left 
     puts "im here on left and my parents parent is not nil" 

     if node.parent.parent.left == node.parent 
      node.parent.parent.left = node 
      node.parent.parent.left.parent = node.parent.parent 
      node.left = temp_parent 
      node.right = temp_parent_right 
      node.left.parent = node 
      unless node.right.nil? 
      node.right.parent = node 
      end 
      node.left.left = temp_node_left 
      node.left.right = temp_node_right 
     elsif node.parent.parent.right == node.parent 
      node.parent.parent.right = node 
      node.parent.parent.right.parent = node.parent.parent 
      node.left = temp_parent 
      node.right = temp_parent_right 
      node.left.parent = node 
      unless node.right.nil? 
      node.right.parent = node 
      end 
      node.left.left = temp_node_left 
      node.left.right = temp_node_right 
     end 

     elsif !node.parent.nil? && node == node.parent.right 

     if node.parent.parent.right == node.parent 
      node.parent.parent.right = node 
      node.parent.parent.right.parent = node.parent.parent 
      node.right = temp_parent 
      node.left = temp_parent_right 
      node.right.parent = node 
      unless node.left.nil? 
      node.left.parent = node 
      end 
      node.left.left = temp_node_left 
      node.left.right = temp_node_right 
     elsif node.parent.parent.left == node.parent 
      node.parent.parent.left = node 
      node.parent.parent.left.parent = node.parent.parent 
      node.left = temp_parent 
      node.left = temp_parent_right 
      node.right.parent = node 
      unless node.right.nil? 
      node.right.parent = node 
      end 
      node.left.left = temp_node_left 
      node.left.right = temp_node_right 
     end 

     end 
    end 
    end 
0

HeapSearchTree#insertは正しく交換するのではなく、ノードを変更するため、これは正しいです。あなたの挿入コードは、ノードのタイトルと評価を変更します。変数matrixは、 "The Matrix"というタイトルのノードにバインドされますが、これは挿入メソッドによって "The Martian"に変更されます。

[2] pry(main)> tree = HeapSearchTree.new 
[3] pry(main)> matrix = Node.new("The Matrix", 87) 
[4] pry(main)> martian = Node.new("The Martian", 92) 

[5] pry(main)> tree.insert(matrix) 
=> #<Node:0x007f92348c7c10 
@left=nil, 
@parent=nil, 
@rating=87, 
@right=nil, 
@title="The Matrix"> 
[6] pry(main)> matrix.object_id 
=> 70132961787400 
[7] pry(main)> matrix.title 
=> "The Matrix" 

[8] pry(main)> tree.insert(martian) 
=> nil 

[9] pry(main)> matrix.object_id 
=> 70132961787400 
[10] pry(main)> matrix.title 
=> "The Martian" 

[11] pry(main)> tree.find(matrix.title) 
END OF RECURSION 
movie_title entered: The Martian 
root.title: The Martian 

これが示すことは、変数matrixに結合したノードは、正しいタイトルが表示されており、したがってそのタイトルを検索すると、正しい結果を返します。私は、あなたが言及したように、ノードを正しく交換するために挿入を再実装するでしょう。

+0

この最後の夜も実現しました、ありがとうございます。 – DustinRW

関連する問題