• By Golang

    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. }