103 lines
2.6 KiB
C#
103 lines
2.6 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
|
|
namespace EventMowForTreasure
|
|
{
|
|
#region A*
|
|
|
|
public class EventMowForTreasurePriorityQueue<T> where T : IComparable<T>
|
|
{
|
|
private readonly List<T> _data = new();
|
|
private readonly Dictionary<T, int> _itemIndices = new();
|
|
|
|
public int Count => _data.Count;
|
|
|
|
public void Enqueue(T item)
|
|
{
|
|
_data.Add(item);
|
|
_itemIndices[item] = _data.Count - 1;
|
|
HeapifyUp(_data.Count - 1);
|
|
}
|
|
|
|
public T Dequeue()
|
|
{
|
|
if (_data.Count == 0)
|
|
throw new InvalidOperationException("Queue is empty");
|
|
|
|
var frontItem = _data[0];
|
|
_itemIndices.Remove(frontItem);
|
|
|
|
if (_data.Count == 1)
|
|
{
|
|
_data.RemoveAt(0);
|
|
}
|
|
else
|
|
{
|
|
var lastItem = _data[_data.Count - 1];
|
|
_data[0] = lastItem;
|
|
_itemIndices[lastItem] = 0;
|
|
_data.RemoveAt(_data.Count - 1);
|
|
HeapifyDown(0);
|
|
}
|
|
|
|
return frontItem;
|
|
}
|
|
|
|
public void UpdateItem(T item)
|
|
{
|
|
if (_itemIndices.TryGetValue(item, out var index))
|
|
{
|
|
HeapifyUp(index);
|
|
HeapifyDown(index);
|
|
}
|
|
}
|
|
|
|
public bool Contains(T item)
|
|
{
|
|
return _itemIndices.ContainsKey(item);
|
|
}
|
|
|
|
private void HeapifyUp(int index)
|
|
{
|
|
while (index > 0)
|
|
{
|
|
var parentIndex = (index - 1) / 2;
|
|
if (_data[index].CompareTo(_data[parentIndex]) >= 0)
|
|
break;
|
|
|
|
Swap(index, parentIndex);
|
|
index = parentIndex;
|
|
}
|
|
}
|
|
|
|
private void HeapifyDown(int index)
|
|
{
|
|
var lastIndex = _data.Count - 1;
|
|
while (true)
|
|
{
|
|
var childIndex = index * 2 + 1;
|
|
if (childIndex > lastIndex) break;
|
|
|
|
var rightChild = childIndex + 1;
|
|
if (rightChild <= lastIndex && _data[rightChild].CompareTo(_data[childIndex]) < 0)
|
|
childIndex = rightChild;
|
|
|
|
if (_data[index].CompareTo(_data[childIndex]) <= 0)
|
|
break;
|
|
|
|
Swap(index, childIndex);
|
|
index = childIndex;
|
|
}
|
|
}
|
|
|
|
private void Swap(int i, int j)
|
|
{
|
|
(_data[i], _data[j]) = (_data[j], _data[i]);
|
|
|
|
_itemIndices[_data[i]] = i;
|
|
_itemIndices[_data[j]] = j;
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
} |