PriorityQueue.cs 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. using System;
  2. using System.Collections.Generic;
  3. namespace OpenVIII.Fields
  4. {
  5. public sealed class PriorityQueue<T>
  6. {
  7. private LinkedList<Item> _list;
  8. public Int32 Count => _list.Count;
  9. public PriorityQueue()
  10. {
  11. _list = new LinkedList<Item>();
  12. }
  13. public void Enqueue(T value, Int32 priority = 0)
  14. {
  15. Item item = new Item(value, priority);
  16. if (_list.Count == 0)
  17. {
  18. _list.AddLast(item);
  19. return;
  20. }
  21. Int32 first = _list.First.Value.Priority;
  22. Int32 last = _list.Last.Value.Priority;
  23. if (Math.Abs(first - priority) < Math.Abs(last - priority))
  24. {
  25. for (var i = _list.First; i != null; i = i.Next)
  26. {
  27. if (i.Value.Priority > priority)
  28. {
  29. _list.AddBefore(i, item);
  30. return;
  31. }
  32. }
  33. }
  34. else
  35. {
  36. for (var i = _list.Last; i != null; i = i.Previous)
  37. {
  38. if (i.Value.Priority <= priority)
  39. {
  40. _list.AddAfter(i, item);
  41. return;
  42. }
  43. }
  44. }
  45. _list.AddLast(item);
  46. }
  47. public T Dequeue()
  48. {
  49. if (TryDequeue(out var value))
  50. return value;
  51. throw new InvalidOperationException("The queue is empty.");
  52. }
  53. public Boolean TryDequeue(out T value)
  54. {
  55. if (Count == 0)
  56. {
  57. value = default(T);
  58. return false;
  59. }
  60. var item = _list.First.Value;
  61. _list.RemoveFirst();
  62. value = item.Value;
  63. return true;
  64. }
  65. public Boolean HasPriority(Int32 priority)
  66. {
  67. if (_list.Count == 0)
  68. return false;
  69. Int32 first = _list.First.Value.Priority;
  70. Int32 last = _list.Last.Value.Priority;
  71. if (Math.Abs(first - priority) < Math.Abs(last - priority))
  72. {
  73. for (var i = _list.First; i != null; i = i.Next)
  74. {
  75. if (i.Value.Priority == priority)
  76. return true;
  77. if (i.Value.Priority > priority)
  78. return false;
  79. }
  80. }
  81. else
  82. {
  83. for (var i = _list.Last; i != null; i = i.Previous)
  84. {
  85. if (i.Value.Priority == priority)
  86. return true;
  87. if (i.Value.Priority < priority)
  88. return false;
  89. }
  90. }
  91. return false;
  92. }
  93. public void Clear()
  94. {
  95. _list.Clear();
  96. }
  97. private sealed class Item
  98. {
  99. public readonly T Value;
  100. public readonly Int32 Priority;
  101. public Item(T value, Int32 priority)
  102. {
  103. Value = value;
  104. Priority = priority;
  105. }
  106. }
  107. }
  108. }