using System; using System.Collections.Generic; namespace EventMowForTreasure { #region A* public class EventMowForTreasurePriorityQueue where T : IComparable { private readonly List _data = new(); private readonly Dictionary _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 }