Advertisement
Guest User

Untitled

a guest
Jun 2nd, 2015
287
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 1.98 KB | None | 0 0
  1. class Heap
  2. def initialize(&block)
  3. @ary = []
  4. @pred = block || -> (a,b) { a < b }
  5. end
  6.  
  7. def <<(value)
  8. n = size
  9.  
  10. # 最後に追加
  11. @ary[n] = value
  12.  
  13. # 適切な場所まで押し上げる
  14. while n != 0
  15. if precede?(@ary[n], @ary[parent(n)])
  16. @ary[parent(n)], @ary[n] = @ary[n], @ary[parent(n)]
  17. n = parent(n)
  18. else
  19. break
  20. end
  21. end
  22.  
  23. self
  24. end
  25.  
  26. def parent(n)
  27. (n-1)/2
  28. end
  29.  
  30. def child_l(n)
  31. 2*n+1
  32. end
  33.  
  34. def child_r(n)
  35. 2*n+2
  36. end
  37.  
  38. def pop
  39. retval = @ary[0]
  40.  
  41. # ヒープを保つ
  42. n = 0
  43.  
  44. # 最後の要素をルートに持ってくる
  45. @ary[n] = @ary[size-1]
  46. @ary.pop
  47.  
  48. # 適切な場所まで押し下げる
  49. loop do
  50. if (child_l(n) < size && !precede?(@ary[n], @ary[child_l(n)])) ||
  51. (child_r(n) < size && !precede?(@ary[n], @ary[child_r(n)]))
  52.  
  53. if child_r(n) >= size || precede?(@ary[child_l(n)], @ary[child_r(n)])
  54. # 左の子と入れ替える
  55. @ary[n], @ary[child_l(n)] = @ary[child_l(n)], @ary[n]
  56. n = child_l(n)
  57. else #
  58. # 右の子と入れ替える
  59. @ary[n], @ary[child_r(n)] = @ary[child_r(n)], @ary[n]
  60. n = child_r(n)
  61. end
  62. else
  63. break
  64. end
  65. end
  66.  
  67. retval
  68. end
  69.  
  70. def empty?
  71. @ary.empty?
  72. end
  73.  
  74. def size
  75. @ary.size
  76. end
  77.  
  78. def to_a
  79. @ary.dup
  80. end
  81.  
  82. # ソート済みの配列を返す
  83. def sort
  84. tmp = @ary.dup
  85. return [].tap do |retval|
  86. retval << pop until empty?
  87. @ary = tmp
  88. end
  89. end
  90.  
  91. private
  92.  
  93. def precede?(a, b)
  94. @pred.(a, b)
  95. end
  96. end
  97.  
  98. def test
  99. # 整数をソート
  100. h = Heap.new
  101. h << 1 << 2 << -1 << 5 << 3
  102. p h.sort
  103.  
  104. # 文字列を長さでソート
  105. h = Heap.new { |a,b| a.size < b.size }
  106. h << 'hello' << 'world' << 'ls' << 'dir' << 'pecarecorder'
  107. p h.sort
  108.  
  109. a = []
  110. h = Heap.new { |a,b| a < b }
  111. 100.times { a << rand }
  112. a.each { |x| h << x }
  113. p h.sort
  114. p a.sort
  115. p h.sort == a.sort
  116. end
  117.  
  118. test if __FILE__ == $0
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement