avl.odin 15 KB

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