prioq.go 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. package main
  2. // Invariant: both children are bigger
  3. type prioq struct {
  4. bintree []*Car
  5. }
  6. func (pq *prioq) Add(car *Car) {
  7. pq.bintree = append(pq.bintree, car)
  8. // Rebalance tree to respect invariant
  9. var i = len(pq.bintree) - 1
  10. var p = (i - 1) / 2
  11. for p >= 0 && pq.bintree[p].Arrival > pq.bintree[i].Arrival {
  12. pq.bintree[p], pq.bintree[i] = pq.bintree[i], pq.bintree[p]
  13. i = p
  14. p = (i - 1) / 2
  15. }
  16. }
  17. func (pq *prioq) Pop() *Car {
  18. if len(pq.bintree) == 0 {
  19. return nil
  20. }
  21. if len(pq.bintree) == 1 {
  22. elem := pq.bintree[0]
  23. pq.bintree = pq.bintree[:0]
  24. return elem
  25. }
  26. elem := pq.bintree[0]
  27. // Put last element at root
  28. pq.bintree[0] = pq.bintree[len(pq.bintree)-1]
  29. // Remove last element
  30. pq.bintree = pq.bintree[:len(pq.bintree)-1]
  31. // 1 9
  32. // 10 9 10 12
  33. // 11 12 13 14 -> 11 12 13 14
  34. // 12
  35. // Rebalance tree to respect invariant
  36. len := len(pq.bintree)
  37. i, left, right := 0, 0, 0
  38. for {
  39. left = 2*i + 1
  40. right = 2*i + 2
  41. if left < len && right < len { // Two children
  42. if pq.bintree[left].Arrival <= pq.bintree[right].Arrival {
  43. if pq.bintree[i].Arrival <= pq.bintree[left].Arrival {
  44. break // Inferior to both children
  45. } else {
  46. pq.bintree[i], pq.bintree[left] = pq.bintree[left], pq.bintree[i]
  47. i = left
  48. }
  49. } else {
  50. if pq.bintree[i].Arrival <= pq.bintree[right].Arrival {
  51. break // Inferior to both children
  52. } else {
  53. pq.bintree[i], pq.bintree[right] = pq.bintree[right], pq.bintree[i]
  54. i = right
  55. }
  56. }
  57. } else if left < len { // One child (left)
  58. if pq.bintree[i].Arrival <= pq.bintree[left].Arrival {
  59. break // Inferior to only child
  60. }
  61. pq.bintree[i], pq.bintree[left] = pq.bintree[left], pq.bintree[i]
  62. i = left
  63. } else { // No child
  64. break
  65. }
  66. }
  67. return elem
  68. }
  69. func (pq *prioq) empty() bool {
  70. return len(pq.bintree) == 0
  71. }