Files
ft/Client/Assets/Scripts/EventMowForTreasure/Act/EventMowForTreasurePriorityQueue.cs
2026-06-29 21:18:33 +08:00

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
}