// MIT License - Copyright (c) 2025 wallstop // Full license text: https://github.com/wallstop/unity-helpers/blob/main/LICENSE namespace WallstopStudios.UnityHelpers.Core.DataStructure { using System; using System.Collections; using System.Collections.Generic; /// /// A priority queue implemented as a thin wrapper around . /// Provides clearer semantics for priority-based task scheduling, A* pathfinding, /// event systems, and AI decision making. Supports both min-priority and max-priority modes. /// /// /// open = new PriorityQueue(Comparer.Create((a, b) => a.F.CompareTo(b.F))); /// open.Enqueue(startNode); /// while (!open.IsEmpty && open.TryDequeue(out PathNode current)) /// { /// // process node /// } /// ]]> /// [Serializable] public sealed class PriorityQueue : IEnumerable { private readonly Heap _heap; /// /// Gets the number of elements in the priority queue. /// public int Count => _heap.Count; /// /// Gets whether the priority queue is empty. /// public bool IsEmpty => _heap.IsEmpty; /// /// Gets the current capacity of the underlying heap. /// public int Capacity => _heap.Capacity; public PriorityQueue() : this(16) { } /// /// Constructs a priority queue with the default comparer (min-priority). /// public PriorityQueue(int capacity) : this(Comparer.Default, capacity) { } /// /// Constructs a priority queue with a custom comparer. /// public PriorityQueue(IComparer comparer, int capacity = 16) { _heap = new Heap(comparer, capacity); } /// /// Constructs a priority queue from an existing collection. /// public PriorityQueue(IEnumerable items, IComparer comparer = null) { _heap = new Heap(items, comparer); } /// /// Creates a min-priority queue (lowest priority dequeued first). /// public static PriorityQueue CreateMin(int capacity = 16) { return new PriorityQueue(Comparer.Default, capacity); } /// /// Creates a max-priority queue (highest priority dequeued first). /// public static PriorityQueue CreateMax(int capacity = 16) { return new PriorityQueue( Comparer.Create((x, y) => Comparer.Default.Compare(y, x)), capacity ); } /// /// Creates a min-priority queue from an existing collection. /// public static PriorityQueue CreateMin(IEnumerable items) { return new PriorityQueue(items, Comparer.Default); } /// /// Creates a max-priority queue from an existing collection. /// public static PriorityQueue CreateMax(IEnumerable items) { return new PriorityQueue( items, Comparer.Create((x, y) => Comparer.Default.Compare(y, x)) ); } /// /// Enqueues an element with its priority in O(log n) time. /// public void Enqueue(T item) { _heap.Add(item); } /// /// Attempts to dequeue the highest priority element in O(log n) time. /// public bool TryDequeue(out T result) { return _heap.TryPop(out result); } /// /// Attempts to peek at the highest priority element without removing it. /// public bool TryPeek(out T result) { return _heap.TryPeek(out result); } /// /// Removes all elements from the priority queue. /// public void Clear() { _heap.Clear(); } /// /// Checks if the priority queue contains a specific element in O(n) time. /// public bool Contains(T item) { return _heap.Contains(item); } /// /// Attempts to update the priority of an element at the specified index. /// The index refers to internal heap storage order, not priority order. /// Returns false if index is invalid. /// public bool TryUpdatePriority(int index, T newValue) { return _heap.TryUpdatePriority(index, newValue); } /// /// Attempts to get the element at the specified internal index. /// The index refers to internal heap storage order, not priority order. /// public bool TryGet(int index, out T result) { return _heap.TryGet(index, out result); } /// /// Returns an array containing all elements (not in priority order). /// public T[] ToArray() { return _heap.ToArray(); } public int ToArray(ref T[] result) { return _heap.ToArray(ref result); } /// /// Trims excess capacity to match the current count. /// public void TrimExcess() { _heap.TrimExcess(); } /// /// Returns an enumerator that iterates through all elements in internal heap order (not priority order). /// Note: Iteration order is NOT sorted by priority. Use DequeueAll for priority-sorted iteration. /// public Heap.HeapEnumerator GetEnumerator() { return _heap.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } } }