priority_queue.erl 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. -module(priority_queue).
  2. -export([empty/0, is_empty/1, size/1, values/1, priorities/1]).
  3. -export([to_list/1, to_orddict/1, from_list/1, from_orddict/1, map_values/2]).
  4. -export([insert/3, insert_many/3]).
  5. -export([find_value/2, delete_value/2, take_value/2, modify_priority/3]).
  6. -export([minimum/1, take_minimum/1, maximum/1, take_maximum/1]).
  7. empty() ->
  8. gb_trees:empty().
  9. is_empty(Queue) ->
  10. gb_trees:is_empty(Queue).
  11. size(Queue) ->
  12. gb_trees:size(Queue).
  13. values(Queue) ->
  14. lists:append(gb_trees:values(Queue)).
  15. priorities(Queue) ->
  16. gb_trees:keys(Queue).
  17. to_orddict(Queue) ->
  18. gb_trees:to_list(Queue).
  19. to_list(Queue) ->
  20. lists:append([ [ {Priority, Val} || Val <- Vals ]
  21. || {Priority, Vals} <- gb_trees:to_list(Queue) ]).
  22. from_orddict(List) ->
  23. gb_trees:from_orddict(List).
  24. from_list(List) ->
  25. lists:foldl(fun({Priority, Val}, Queue) -> insert(Priority, Val, Queue) end,
  26. empty(), List).
  27. map_values(Func, Queue) ->
  28. gb_trees:map(fun(_Key, Vals) -> lists:map(Func, Vals) end, Queue).
  29. insert(Priority, Val, Queue) ->
  30. case gb_trees:lookup(Priority, Queue) of
  31. none ->
  32. gb_trees:insert(Priority, [Val], Queue);
  33. {value, Prev} ->
  34. gb_trees:update(Priority, [Val|Prev], Queue)
  35. end.
  36. insert_many(Priority, Vals, Queue) when is_list(Vals) ->
  37. case gb_trees:lookup(Priority, Queue) of
  38. none ->
  39. gb_trees:insert(Priority, Vals, Queue);
  40. {value, Prev} ->
  41. gb_trees:update(Priority, Vals++Prev, Queue)
  42. end.
  43. find_value(Val, Queue) ->
  44. case [ {P, V} || {P, Vs} <- to_orddict(Queue), V <- Vs, V == Val ] of
  45. [{Priority, Val}] -> {Priority, Val};
  46. [] -> none
  47. end.
  48. delete_value(Val, Queue) ->
  49. gb_trees:map(fun(_Key, Vs) -> [ V || V <- Vs, V =/= Val ] end, Queue).
  50. take_value(Val, Queue) ->
  51. case [ {P, V, Vs} || {P, Vs} <- to_orddict(Queue), V <- Vs, V == Val ] of
  52. [{Priority, Val, Vals}] ->
  53. Queue2 = case [ V || V <- Vals, V =/= Val ] of
  54. [] -> gb_trees:delete(Priority, Queue);
  55. Vals2 -> gb_trees:update(Priority, Vals2, Queue)
  56. end,
  57. {Priority, Val, Queue2};
  58. [] -> none
  59. end.
  60. modify_priority(Val, Func, Queue) when is_function(Func) ->
  61. case take_value(Val, Queue) of
  62. {Priority, Val, Queue2} ->
  63. insert(Func(Priority), Val, Queue2);
  64. none ->
  65. Queue
  66. end.
  67. minimum(Queue) ->
  68. case gb_trees:smallest(Queue) of
  69. {Priority, [Val|_]} -> {Priority, Val};
  70. {Priority, []} -> minimum(gb_trees:delete(Priority, Queue))
  71. end.
  72. maximum(Queue) ->
  73. case gb_trees:largest(Queue) of
  74. {Priority, [Val|_]} -> {Priority, Val};
  75. {Priority, []} -> maximum(gb_trees:delete(Priority, Queue))
  76. end.
  77. take_minimum(Queue) ->
  78. case gb_trees:take_smallest(Queue) of
  79. {_Priority, [], Queue2} ->
  80. take_minimum(Queue2);
  81. {Priority, [Val], Queue2} ->
  82. {Priority, Val, Queue2};
  83. {Priority, [Val|Vals], Queue2} ->
  84. {Priority, Val, gb_trees:insert(Priority, Vals, Queue2)}
  85. end.
  86. take_maximum(Queue) ->
  87. case gb_trees:take_largest(Queue) of
  88. {_Priority, [], Queue2} ->
  89. take_maximum(Queue2);
  90. {Priority, [Val], Queue2} ->
  91. {Priority, Val, Queue2};
  92. {Priority, [Val|Vals], Queue2} ->
  93. {Priority, Val, gb_trees:insert(Priority, Vals, Queue2)}
  94. end.