avl.odin 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678
  1. /*
  2. package avl implements an AVL tree.
  3. The implementation is non-intrusive, and non-recursive.
  4. */
  5. package container_avl
  6. import "base:intrinsics"
  7. import "base:runtime"
  8. import "core:slice"
  9. _ :: intrinsics
  10. _ :: runtime
  11. // Originally based on the CC0 implementation by Eric Biggers
  12. // See: https://github.com/ebiggers/avl_tree/
  13. // Direction specifies the traversal direction for a tree iterator.
  14. Direction :: enum i8 {
  15. // Backward is the in-order backwards direction.
  16. Backward = -1,
  17. // Forward is the in-order forwards direction.
  18. Forward = 1,
  19. }
  20. // Ordering specifies order when inserting/finding values into the tree.
  21. Ordering :: slice.Ordering
  22. // Tree is an AVL tree.
  23. Tree :: struct($Value: typeid) {
  24. // user_data is a parameter that will be passed to the on_remove
  25. // callback.
  26. user_data: rawptr,
  27. // on_remove is an optional callback that can be called immediately
  28. // after a node is removed from the tree.
  29. on_remove: proc(value: Value, user_data: rawptr),
  30. _root: ^Node(Value),
  31. _node_allocator: runtime.Allocator,
  32. _cmp_fn: proc(a, b: Value) -> Ordering,
  33. _size: int,
  34. }
  35. // Node is an AVL tree node.
  36. //
  37. // WARNING: It is unsafe to mutate value if the node is part of a tree
  38. // if doing so will alter the Node's sort position relative to other
  39. // elements in the tree.
  40. Node :: struct($Value: typeid) {
  41. value: Value,
  42. _parent: ^Node(Value),
  43. _left: ^Node(Value),
  44. _right: ^Node(Value),
  45. _balance: i8,
  46. }
  47. // Iterator is a tree iterator.
  48. //
  49. // WARNING: It is unsafe to modify the tree while iterating, except via
  50. // the iterator_remove method.
  51. Iterator :: struct($Value: typeid) {
  52. _tree: ^Tree(Value),
  53. _cur: ^Node(Value),
  54. _next: ^Node(Value),
  55. _direction: Direction,
  56. _called_next: bool,
  57. }
  58. // init initializes a tree.
  59. init :: proc {
  60. init_ordered,
  61. init_cmp,
  62. }
  63. // init_cmp initializes a tree.
  64. init_cmp :: proc(
  65. t: ^$T/Tree($Value),
  66. cmp_fn: proc(a, b: Value) -> Ordering,
  67. node_allocator := context.allocator,
  68. ) {
  69. t._root = nil
  70. t._node_allocator = node_allocator
  71. t._cmp_fn = cmp_fn
  72. t._size = 0
  73. }
  74. // init_ordered initializes a tree containing ordered items, with
  75. // a comparison function that results in an ascending order sort.
  76. init_ordered :: proc(
  77. t: ^$T/Tree($Value),
  78. node_allocator := context.allocator,
  79. ) where intrinsics.type_is_ordered_numeric(Value) {
  80. init_cmp(t, slice.cmp_proc(Value), node_allocator)
  81. }
  82. // destroy de-initializes a tree.
  83. destroy :: proc(t: ^$T/Tree($Value), call_on_remove: bool = true) {
  84. iter := iterator(t, Direction.Forward)
  85. for _ in iterator_next(&iter) {
  86. iterator_remove(&iter, call_on_remove)
  87. }
  88. }
  89. // len returns the number of elements in the tree.
  90. len :: proc "contextless" (t: ^$T/Tree($Value)) -> int {
  91. return t._size
  92. }
  93. // first returns the first node in the tree (in-order) or nil iff
  94. // the tree is empty.
  95. first :: proc "contextless" (t: ^$T/Tree($Value)) -> ^Node(Value) {
  96. return tree_first_or_last_in_order(t, Direction.Backward)
  97. }
  98. // last returns the last element in the tree (in-order) or nil iff
  99. // the tree is empty.
  100. last :: proc "contextless" (t: ^$T/Tree($Value)) -> ^Node(Value) {
  101. return tree_first_or_last_in_order(t, Direction.Forward)
  102. }
  103. // find finds the value in the tree, and returns the corresponding
  104. // node or nil iff the value is not present.
  105. find :: proc(t: ^$T/Tree($Value), value: Value) -> ^Node(Value) {
  106. cur := t._root
  107. descend_loop: for cur != nil {
  108. switch t._cmp_fn(value, cur.value) {
  109. case .Less:
  110. cur = cur._left
  111. case .Greater:
  112. cur = cur._right
  113. case .Equal:
  114. break descend_loop
  115. }
  116. }
  117. return cur
  118. }
  119. // find_or_insert attempts to insert the value into the tree, and returns
  120. // the node, a boolean indicating if the value was inserted, and the
  121. // node allocator error if relevant. If the value is already
  122. // present, the existing node is returned un-altered.
  123. find_or_insert :: proc(
  124. t: ^$T/Tree($Value),
  125. value: Value,
  126. ) -> (
  127. n: ^Node(Value),
  128. inserted: bool,
  129. err: runtime.Allocator_Error,
  130. ) {
  131. n_ptr := &t._root
  132. for n_ptr^ != nil {
  133. n = n_ptr^
  134. switch t._cmp_fn(value, n.value) {
  135. case .Less:
  136. n_ptr = &n._left
  137. case .Greater:
  138. n_ptr = &n._right
  139. case .Equal:
  140. return
  141. }
  142. }
  143. parent := n
  144. n = new(Node(Value), t._node_allocator) or_return
  145. n.value = value
  146. n._parent = parent
  147. n_ptr^ = n
  148. tree_rebalance_after_insert(t, n)
  149. t._size += 1
  150. inserted = true
  151. return
  152. }
  153. // remove removes a node or value from the tree, and returns true iff the
  154. // removal was successful. While the node's value will be left intact,
  155. // the node itself will be freed via the tree's node allocator.
  156. remove :: proc {
  157. remove_value,
  158. remove_node,
  159. }
  160. // remove_value removes a value from the tree, and returns true iff the
  161. // removal was successful. While the node's value will be left intact,
  162. // the node itself will be freed via the tree's node allocator.
  163. remove_value :: proc(t: ^$T/Tree($Value), value: Value, call_on_remove: bool = true) -> bool {
  164. n := find(t, value)
  165. if n == nil {
  166. return false
  167. }
  168. return remove_node(t, n, call_on_remove)
  169. }
  170. // remove_node removes a node from the tree, and returns true iff the
  171. // removal was successful. While the node's value will be left intact,
  172. // the node itself will be freed via the tree's node allocator.
  173. remove_node :: proc(t: ^$T/Tree($Value), node: ^Node(Value), call_on_remove: bool = true) -> bool {
  174. if node._parent == node || (node._parent == nil && t._root != node) {
  175. return false
  176. }
  177. defer {
  178. if call_on_remove && t.on_remove != nil {
  179. t.on_remove(node.value, t.user_data)
  180. }
  181. free(node, t._node_allocator)
  182. }
  183. parent: ^Node(Value)
  184. left_deleted: bool
  185. t._size -= 1
  186. if node._left != nil && node._right != nil {
  187. parent, left_deleted = tree_swap_with_successor(t, node)
  188. } else {
  189. child := node._left
  190. if child == nil {
  191. child = node._right
  192. }
  193. parent = node._parent
  194. if parent != nil {
  195. if node == parent._left {
  196. parent._left = child
  197. left_deleted = true
  198. } else {
  199. parent._right = child
  200. left_deleted = false
  201. }
  202. if child != nil {
  203. child._parent = parent
  204. }
  205. } else {
  206. if child != nil {
  207. child._parent = parent
  208. }
  209. t._root = child
  210. node_reset(node)
  211. return true
  212. }
  213. }
  214. for {
  215. if left_deleted {
  216. parent = tree_handle_subtree_shrink(t, parent, +1, &left_deleted)
  217. } else {
  218. parent = tree_handle_subtree_shrink(t, parent, -1, &left_deleted)
  219. }
  220. if parent == nil {
  221. break
  222. }
  223. }
  224. node_reset(node)
  225. return true
  226. }
  227. // iterator returns a tree iterator in the specified direction.
  228. iterator :: proc "contextless" (t: ^$T/Tree($Value), direction: Direction) -> Iterator(Value) {
  229. it: Iterator(Value)
  230. it._tree = transmute(^Tree(Value))t
  231. it._direction = direction
  232. iterator_first(&it)
  233. return it
  234. }
  235. // iterator_from_pos returns a tree iterator in the specified direction,
  236. // spanning the range [pos, last] (inclusive).
  237. iterator_from_pos :: proc "contextless" (
  238. t: ^$T/Tree($Value),
  239. pos: ^Node(Value),
  240. direction: Direction,
  241. ) -> Iterator(Value) {
  242. it: Iterator(Value)
  243. it._tree = transmute(^Tree(Value))t
  244. it._direction = direction
  245. it._next = nil
  246. it._called_next = false
  247. if it._cur = pos; pos != nil {
  248. it._next = node_next_or_prev_in_order(it._cur, it._direction)
  249. }
  250. return it
  251. }
  252. // iterator_get returns the node currently pointed to by the iterator,
  253. // or nil iff the node has been removed, the tree is empty, or the end
  254. // of the tree has been reached.
  255. iterator_get :: proc "contextless" (it: ^$I/Iterator($Value)) -> ^Node(Value) {
  256. return it._cur
  257. }
  258. // iterator_remove removes the node currently pointed to by the iterator,
  259. // and returns true iff the removal was successful. Semantics are the
  260. // same as the Tree remove.
  261. iterator_remove :: proc(it: ^$I/Iterator($Value), call_on_remove: bool = true) -> bool {
  262. if it._cur == nil {
  263. return false
  264. }
  265. ok := remove_node(it._tree, it._cur, call_on_remove)
  266. if ok {
  267. it._cur = nil
  268. }
  269. return ok
  270. }
  271. // iterator_next advances the iterator and returns the (node, true) or
  272. // or (nil, false) iff the end of the tree has been reached.
  273. //
  274. // Note: The first call to iterator_next will return the first node instead
  275. // of advancing the iterator.
  276. iterator_next :: proc "contextless" (it: ^$I/Iterator($Value)) -> (^Node(Value), bool) {
  277. // This check is needed so that the first element gets returned from
  278. // a brand-new iterator, and so that the somewhat contrived case where
  279. // iterator_remove is called before the first call to iterator_next
  280. // returns the correct value.
  281. if !it._called_next {
  282. it._called_next = true
  283. // There can be the contrived case where iterator_remove is
  284. // called before ever calling iterator_next, which needs to be
  285. // handled as an actual call to next.
  286. //
  287. // If this happens it._cur will be nil, so only return the
  288. // first value, if it._cur is valid.
  289. if it._cur != nil {
  290. return it._cur, true
  291. }
  292. }
  293. if it._next == nil {
  294. return nil, false
  295. }
  296. it._cur = it._next
  297. it._next = node_next_or_prev_in_order(it._cur, it._direction)
  298. return it._cur, true
  299. }
  300. @(private)
  301. tree_first_or_last_in_order :: proc "contextless" (
  302. t: ^$T/Tree($Value),
  303. direction: Direction,
  304. ) -> ^Node(Value) {
  305. first, sign := t._root, i8(direction)
  306. if first != nil {
  307. for {
  308. tmp := node_get_child(first, +sign)
  309. if tmp == nil {
  310. break
  311. }
  312. first = tmp
  313. }
  314. }
  315. return first
  316. }
  317. @(private)
  318. tree_replace_child :: proc "contextless" (
  319. t: ^$T/Tree($Value),
  320. parent, old_child, new_child: ^Node(Value),
  321. ) {
  322. if parent != nil {
  323. if old_child == parent._left {
  324. parent._left = new_child
  325. } else {
  326. parent._right = new_child
  327. }
  328. } else {
  329. t._root = new_child
  330. }
  331. }
  332. @(private)
  333. tree_rotate :: proc "contextless" (t: ^$T/Tree($Value), a: ^Node(Value), sign: i8) {
  334. b := node_get_child(a, -sign)
  335. e := node_get_child(b, +sign)
  336. p := a._parent
  337. node_set_child(a, -sign, e)
  338. a._parent = b
  339. node_set_child(b, +sign, a)
  340. b._parent = p
  341. if e != nil {
  342. e._parent = a
  343. }
  344. tree_replace_child(t, p, a, b)
  345. }
  346. @(private)
  347. tree_double_rotate :: proc "contextless" (
  348. t: ^$T/Tree($Value),
  349. b, a: ^Node(Value),
  350. sign: i8,
  351. ) -> ^Node(Value) {
  352. e := node_get_child(b, +sign)
  353. f := node_get_child(e, -sign)
  354. g := node_get_child(e, +sign)
  355. p := a._parent
  356. e_bal := e._balance
  357. node_set_child(a, -sign, g)
  358. a_bal := -e_bal
  359. if sign * e_bal >= 0 {
  360. a_bal = 0
  361. }
  362. node_set_parent_balance(a, e, a_bal)
  363. node_set_child(b, +sign, f)
  364. b_bal := -e_bal
  365. if sign * e_bal <= 0 {
  366. b_bal = 0
  367. }
  368. node_set_parent_balance(b, e, b_bal)
  369. node_set_child(e, +sign, a)
  370. node_set_child(e, -sign, b)
  371. node_set_parent_balance(e, p, 0)
  372. if g != nil {
  373. g._parent = a
  374. }
  375. if f != nil {
  376. f._parent = b
  377. }
  378. tree_replace_child(t, p, a, e)
  379. return e
  380. }
  381. @(private)
  382. tree_handle_subtree_growth :: proc "contextless" (
  383. t: ^$T/Tree($Value),
  384. node, parent: ^Node(Value),
  385. sign: i8,
  386. ) -> bool {
  387. old_balance_factor := parent._balance
  388. if old_balance_factor == 0 {
  389. node_adjust_balance_factor(parent, sign)
  390. return false
  391. }
  392. new_balance_factor := old_balance_factor + sign
  393. if new_balance_factor == 0 {
  394. node_adjust_balance_factor(parent, sign)
  395. return true
  396. }
  397. if sign * node._balance > 0 {
  398. tree_rotate(t, parent, -sign)
  399. node_adjust_balance_factor(parent, -sign)
  400. node_adjust_balance_factor(node, -sign)
  401. } else {
  402. tree_double_rotate(t, node, parent, -sign)
  403. }
  404. return true
  405. }
  406. @(private)
  407. tree_rebalance_after_insert :: proc "contextless" (t: ^$T/Tree($Value), inserted: ^Node(Value)) {
  408. node, parent := inserted, inserted._parent
  409. switch {
  410. case parent == nil:
  411. return
  412. case node == parent._left:
  413. node_adjust_balance_factor(parent, -1)
  414. case:
  415. node_adjust_balance_factor(parent, +1)
  416. }
  417. if parent._balance == 0 {
  418. return
  419. }
  420. for done := false; !done; {
  421. node = parent
  422. if parent = node._parent; parent == nil {
  423. return
  424. }
  425. if node == parent._left {
  426. done = tree_handle_subtree_growth(t, node, parent, -1)
  427. } else {
  428. done = tree_handle_subtree_growth(t, node, parent, +1)
  429. }
  430. }
  431. }
  432. @(private)
  433. tree_swap_with_successor :: proc "contextless" (
  434. t: ^$T/Tree($Value),
  435. x: ^Node(Value),
  436. ) -> (
  437. ^Node(Value),
  438. bool,
  439. ) {
  440. ret: ^Node(Value)
  441. left_deleted: bool
  442. y := x._right
  443. if y._left == nil {
  444. ret = y
  445. } else {
  446. q: ^Node(Value)
  447. for {
  448. q = y
  449. if y = y._left; y._left == nil {
  450. break
  451. }
  452. }
  453. if q._left = y._right; q._left != nil {
  454. q._left._parent = q
  455. }
  456. y._right = x._right
  457. x._right._parent = y
  458. ret = q
  459. left_deleted = true
  460. }
  461. y._left = x._left
  462. x._left._parent = y
  463. y._parent = x._parent
  464. y._balance = x._balance
  465. tree_replace_child(t, x._parent, x, y)
  466. return ret, left_deleted
  467. }
  468. @(private)
  469. tree_handle_subtree_shrink :: proc "contextless" (
  470. t: ^$T/Tree($Value),
  471. parent: ^Node(Value),
  472. sign: i8,
  473. left_deleted: ^bool,
  474. ) -> ^Node(Value) {
  475. old_balance_factor := parent._balance
  476. if old_balance_factor == 0 {
  477. node_adjust_balance_factor(parent, sign)
  478. return nil
  479. }
  480. node: ^Node(Value)
  481. new_balance_factor := old_balance_factor + sign
  482. if new_balance_factor == 0 {
  483. node_adjust_balance_factor(parent, sign)
  484. node = parent
  485. } else {
  486. node = node_get_child(parent, sign)
  487. if sign * node._balance >= 0 {
  488. tree_rotate(t, parent, -sign)
  489. if node._balance == 0 {
  490. node_adjust_balance_factor(node, -sign)
  491. return nil
  492. }
  493. node_adjust_balance_factor(parent, -sign)
  494. node_adjust_balance_factor(node, -sign)
  495. } else {
  496. node = tree_double_rotate(t, node, parent, -sign)
  497. }
  498. }
  499. parent := parent
  500. if parent = node._parent; parent != nil {
  501. left_deleted^ = node == parent._left
  502. }
  503. return parent
  504. }
  505. @(private)
  506. node_reset :: proc "contextless" (n: ^Node($Value)) {
  507. // Mostly pointless as n will be deleted after this is called, but
  508. // attempt to be able to catch cases of n not being in the tree.
  509. n._parent = n
  510. n._left = nil
  511. n._right = nil
  512. n._balance = 0
  513. }
  514. @(private)
  515. node_set_parent_balance :: #force_inline proc "contextless" (
  516. n, parent: ^Node($Value),
  517. balance: i8,
  518. ) {
  519. n._parent = parent
  520. n._balance = balance
  521. }
  522. @(private)
  523. node_get_child :: #force_inline proc "contextless" (n: ^Node($Value), sign: i8) -> ^Node(Value) {
  524. if sign < 0 {
  525. return n._left
  526. }
  527. return n._right
  528. }
  529. @(private)
  530. node_next_or_prev_in_order :: proc "contextless" (
  531. n: ^Node($Value),
  532. direction: Direction,
  533. ) -> ^Node(Value) {
  534. next, tmp: ^Node(Value)
  535. sign := i8(direction)
  536. if next = node_get_child(n, +sign); next != nil {
  537. for {
  538. tmp = node_get_child(next, -sign)
  539. if tmp == nil {
  540. break
  541. }
  542. next = tmp
  543. }
  544. } else {
  545. tmp, next = n, n._parent
  546. for next != nil && tmp == node_get_child(next, +sign) {
  547. tmp, next = next, next._parent
  548. }
  549. }
  550. return next
  551. }
  552. @(private)
  553. node_set_child :: #force_inline proc "contextless" (
  554. n: ^Node($Value),
  555. sign: i8,
  556. child: ^Node(Value),
  557. ) {
  558. if sign < 0 {
  559. n._left = child
  560. } else {
  561. n._right = child
  562. }
  563. }
  564. @(private)
  565. node_adjust_balance_factor :: #force_inline proc "contextless" (n: ^Node($Value), amount: i8) {
  566. n._balance += amount
  567. }
  568. @(private)
  569. iterator_first :: proc "contextless" (it: ^Iterator($Value)) {
  570. // This is private because behavior when the user manually calls
  571. // iterator_first followed by iterator_next is unintuitive, since
  572. // the first call to iterator_next MUST return the first node
  573. // instead of advancing so that `for node in iterator_next(&next)`
  574. // works as expected.
  575. switch it._direction {
  576. case .Forward:
  577. it._cur = tree_first_or_last_in_order(it._tree, .Backward)
  578. case .Backward:
  579. it._cur = tree_first_or_last_in_order(it._tree, .Forward)
  580. }
  581. it._next = nil
  582. it._called_next = false
  583. if it._cur != nil {
  584. it._next = node_next_or_prev_in_order(it._cur, it._direction)
  585. }
  586. }