By Golang

  1. // Package binarysearchtree creates a ItemBinarySearchTree data structure for the Item type
  2. package binarysearchtree
  3. import (
  4. "fmt"
  5. "sync"
  6. )
  7. // Item the type of the binary search tree
  8. type Item interface{}
  9. // Node a single node that composes the tree
  10. type Node struct {
  11. key int
  12. value Item
  13. left *Node //left
  14. right *Node //right
  15. }
  16. // ItemBinarySearchTree the binary search tree of Items
  17. type ItemBinarySearchTree struct {
  18. root *Node
  19. lock sync.RWMutex
  20. }
  21. // Insert inserts the Item t in the tree
  22. func (bst *ItemBinarySearchTree) Insert(key int, value Item) {
  23. bst.lock.Lock()
  24. defer bst.lock.Unlock()
  25. n := &Node{key, value, nil, nil}
  26. if bst.root == nil {
  27. bst.root = n
  28. } else {
  29. insertNode(bst.root, n)
  30. }
  31. }
  32. // internal function to find the correct place for a node in a tree
  33. func insertNode(node, newNode *Node) {
  34. if newNode.key < node.key {
  35. if node.left == nil {
  36. node.left = newNode
  37. } else {
  38. insertNode(node.left, newNode)
  39. }
  40. } else {
  41. if node.right == nil {
  42. node.right = newNode
  43. } else {
  44. insertNode(node.right, newNode)
  45. }
  46. }
  47. }
  48. // InOrderTraverse visits all nodes with in-order traversing
  49. func (bst *ItemBinarySearchTree) InOrderTraverse(f func(Item)) {
  50. bst.lock.RLock()
  51. defer bst.lock.RUnlock()
  52. inOrderTraverse(bst.root, f)
  53. }
  54. // internal recursive function to traverse in order
  55. func inOrderTraverse(n *Node, f func(Item)) {
  56. if n != nil {
  57. inOrderTraverse(n.left, f)
  58. f(n.value)
  59. inOrderTraverse(n.right, f)
  60. }
  61. }
  62. // PreOrderTraverse visits all nodes with pre-order traversing
  63. func (bst *ItemBinarySearchTree) PreOrderTraverse(f func(Item)) {
  64. bst.lock.Lock()
  65. defer bst.lock.Unlock()
  66. preOrderTraverse(bst.root, f)
  67. }
  68. // internal recursive function to traverse pre order
  69. func preOrderTraverse(n *Node, f func(Item)) {
  70. if n != nil {
  71. f(n.value)
  72. preOrderTraverse(n.left, f)
  73. preOrderTraverse(n.right, f)
  74. }
  75. }
  76. // PostOrderTraverse visits all nodes with post-order traversing
  77. func (bst *ItemBinarySearchTree) PostOrderTraverse(f func(Item)) {
  78. bst.lock.Lock()
  79. defer bst.lock.Unlock()
  80. postOrderTraverse(bst.root, f)
  81. }
  82. // internal recursive function to traverse post order
  83. func postOrderTraverse(n *Node, f func(Item)) {
  84. if n != nil {
  85. postOrderTraverse(n.left, f)
  86. postOrderTraverse(n.right, f)
  87. f(n.value)
  88. }
  89. }
  90. // Min returns the Item with min value stored in the tree
  91. func (bst *ItemBinarySearchTree) Min() *Item {
  92. bst.lock.RLock()
  93. defer bst.lock.RUnlock()
  94. n := bst.root
  95. if n == nil {
  96. return nil
  97. }
  98. for {
  99. if n.left == nil {
  100. return &n.value
  101. }
  102. n = n.left
  103. }
  104. }
  105. // Max returns the Item with max value stored in the tree
  106. func (bst *ItemBinarySearchTree) Max() *Item {
  107. bst.lock.RLock()
  108. defer bst.lock.RUnlock()
  109. n := bst.root
  110. if n == nil {
  111. return nil
  112. }
  113. for {
  114. if n.right == nil {
  115. return &n.value
  116. }
  117. n = n.right
  118. }
  119. }
  120. // Search returns true if the Item t exists in the tree
  121. func (bst *ItemBinarySearchTree) Search(key int) bool {
  122. bst.lock.RLock()
  123. defer bst.lock.RUnlock()
  124. return search(bst.root, key)
  125. }
  126. // internal recursive function to search an item in the tree
  127. func search(n *Node, key int) bool {
  128. if n == nil {
  129. return false
  130. }
  131. if key < n.key {
  132. return search(n.left, key)
  133. }
  134. if key > n.key {
  135. return search(n.right, key)
  136. }
  137. return true
  138. }
  139. // Remove removes the Item with key `key` from the tree
  140. func (bst *ItemBinarySearchTree) Remove(key int) {
  141. bst.lock.Lock()
  142. defer bst.lock.Unlock()
  143. remove(bst.root, key)
  144. }
  145. // internal recursive function to remove an item
  146. func remove(node *Node, key int) *Node {
  147. if node == nil {
  148. return nil
  149. }
  150. if key < node.key {
  151. node.left = remove(node.left, key)
  152. return node
  153. }
  154. if key > node.key {
  155. node.right = remove(node.right, key)
  156. return node
  157. }
  158. // key == node.key
  159. if node.left == nil && node.right == nil {
  160. node = nil
  161. return nil
  162. }
  163. if node.left == nil {
  164. node = node.right
  165. return node
  166. }
  167. if node.right == nil {
  168. node = node.left
  169. return node
  170. }
  171. leftmostrightside := node.right
  172. for {
  173. //find smallest value on the right side
  174. if leftmostrightside != nil && leftmostrightside.left != nil {
  175. leftmostrightside = leftmostrightside.left
  176. } else {
  177. break
  178. }
  179. }
  180. node.key, node.value = leftmostrightside.key, leftmostrightside.value
  181. node.right = remove(node.right, node.key)
  182. return node
  183. }
  184. // String prints a visual representation of the tree
  185. func (bst *ItemBinarySearchTree) String() {
  186. bst.lock.Lock()
  187. defer bst.lock.Unlock()
  188. fmt.Println("------------------------------------------------")
  189. stringify(bst.root, 0)
  190. fmt.Println("------------------------------------------------")
  191. }
  192. // internal recursive function to print a tree
  193. func stringify(n *Node, level int) {
  194. if n != nil {
  195. format := ""
  196. for i := 0; i < level; i++ {
  197. format += " "
  198. }
  199. format += "---[ "
  200. level++
  201. stringify(n.left, level)
  202. fmt.Printf(format+"%d\n", n.key)
  203. stringify(n.right, level)
  204. }
  205. }