avl_tree.sf 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. #!/usr/bin/ruby
  2. #
  3. ## https://rosettacode.org/wiki/AVL_tree
  4. #
  5. class AVLtree {
  6. has root = nil
  7. struct Node {
  8. Number key,
  9. Number balance = 0,
  10. Node left = nil,
  11. Node right = nil,
  12. Node parent = nil,
  13. }
  14. method insert(key) {
  15. if (root == nil) {
  16. root = Node(key)
  17. return true
  18. }
  19. var n = root
  20. var parent = nil
  21. loop {
  22. if (n.key == key) {
  23. return false
  24. }
  25. parent = n
  26. var goLeft = (n.key > key)
  27. n = (goLeft ? n.left : n.right)
  28. if (n == nil) {
  29. var tn = Node(key, parent: parent)
  30. if (goLeft) {
  31. parent.left = tn
  32. }
  33. else {
  34. parent.right = tn
  35. }
  36. self.rebalance(parent)
  37. break
  38. }
  39. }
  40. return true
  41. }
  42. method delete_key(delKey) {
  43. if (root == nil) { return() }
  44. var n = root
  45. var parent = root
  46. var delNode = nil
  47. var child = root
  48. while (child != nil) {
  49. parent = n
  50. n = child
  51. child = (delKey >= n.key ? n.right : n.left)
  52. if (delKey == n.key) {
  53. delNode = n
  54. }
  55. }
  56. if (delNode != nil) {
  57. delNode.key = n.key
  58. child = (n.left != nil ? n.left : n.right)
  59. if (root.key == delKey) {
  60. root = child
  61. }
  62. else {
  63. if (parent.left == n) {
  64. parent.left = child
  65. }
  66. else {
  67. parent.right = child
  68. }
  69. self.rebalance(parent)
  70. }
  71. }
  72. }
  73. method rebalance(n) {
  74. if (n == nil) { return() }
  75. self.setBalance(n)
  76. given (n.balance) {
  77. when (-2) {
  78. if (self.height(n.left.left) >= self.height(n.left.right)) {
  79. n = self.rotate(n, :right)
  80. }
  81. else {
  82. n = self.rotate_twice(n, :left, :right)
  83. }
  84. }
  85. when (2) {
  86. if (self.height(n.right.right) >= self.height(n.right.left)) {
  87. n = self.rotate(n, :left)
  88. }
  89. else {
  90. n = self.rotate_twice(n, :right, :left)
  91. }
  92. }
  93. }
  94. if (n.parent != nil) {
  95. self.rebalance(n.parent)
  96. }
  97. else {
  98. root = n
  99. }
  100. }
  101. method rotate(a, dir) {
  102. var b = (dir == :left ? a.right : a.left)
  103. b.parent = a.parent
  104. (dir == :left) ? (a.right = b.left)
  105. : (a.left = b.right)
  106. if (a.right != nil) {
  107. a.right.parent = a
  108. }
  109. b.$dir = a
  110. a.parent = b
  111. if (b.parent != nil) {
  112. if (b.parent.right == a) {
  113. b.parent.right = b
  114. }
  115. else {
  116. b.parent.left = b
  117. }
  118. }
  119. self.setBalance(a, b)
  120. return b
  121. }
  122. method rotate_twice(n, dir1, dir2) {
  123. n.left = self.rotate(n.left, dir1)
  124. self.rotate(n, dir2)
  125. }
  126. method height(n) {
  127. if (n == nil) { return -1 }
  128. 1 + Math.max(self.height(n.left), self.height(n.right))
  129. }
  130. method setBalance(*nodes) {
  131. nodes.each { |n|
  132. n.balance = (self.height(n.right) - self.height(n.left))
  133. }
  134. }
  135. method printBalance {
  136. self.printBalance(root)
  137. }
  138. method printBalance(n) {
  139. if (n != nil) {
  140. self.printBalance(n.left)
  141. print(n.balance, ' ')
  142. self.printBalance(n.right)
  143. }
  144. }
  145. }
  146. var tree = AVLtree()
  147. say "Inserting values 1 to 10"
  148. 10.times { |i| tree.insert(i) }
  149. print "Printing balance: "
  150. tree.printBalance
  151. print "\n"