diff options
Diffstat (limited to 'UnityCollection/Assets/Infrastructure/CollectionExtends')
-rw-r--r-- | UnityCollection/Assets/Infrastructure/CollectionExtends/MinHeap.cs | 157 | ||||
-rw-r--r-- | UnityCollection/Assets/Infrastructure/CollectionExtends/MinHeap.cs.meta | 11 |
2 files changed, 168 insertions, 0 deletions
diff --git a/UnityCollection/Assets/Infrastructure/CollectionExtends/MinHeap.cs b/UnityCollection/Assets/Infrastructure/CollectionExtends/MinHeap.cs new file mode 100644 index 0000000..420f146 --- /dev/null +++ b/UnityCollection/Assets/Infrastructure/CollectionExtends/MinHeap.cs @@ -0,0 +1,157 @@ +using System; +using System.Collections.Generic; + +namespace CollectionExtend +{ + public class MinHeap<T> + { + private const int InitialCapacity = 4; + + private T[] _arr; + private int _lastItemIndex; + private IComparer<T> _comparer; + + public MinHeap() + : this(InitialCapacity, Comparer<T>.Default) + { + } + + public MinHeap(int capacity) + : this(capacity, Comparer<T>.Default) + { + } + + public MinHeap(Comparison<T> comparison) + : this(InitialCapacity, Comparer<T>.Create(comparison)) + { + } + + public MinHeap(IComparer<T> comparer) + : this(InitialCapacity, comparer) + { + } + + public MinHeap(int capacity, IComparer<T> comparer) + { + _arr = new T[capacity]; + _lastItemIndex = -1; + _comparer = comparer; + } + + public int Count + { + get + { + return _lastItemIndex + 1; + } + } + + public void Add(T item) + { + if (_lastItemIndex == _arr.Length - 1) + { + Resize(); + } + + _lastItemIndex++; + _arr[_lastItemIndex] = item; + + MinHeapifyUp(_lastItemIndex); + } + + public T Remove() + { + if (_lastItemIndex == -1) + { + throw new InvalidOperationException("The heap is empty"); + } + + T removedItem = _arr[0]; + _arr[0] = _arr[_lastItemIndex]; + _lastItemIndex--; + + MinHeapifyDown(0); + + return removedItem; + } + + public T Peek() + { + if (_lastItemIndex == -1) + { + throw new InvalidOperationException("The heap is empty"); + } + + return _arr[0]; + } + + public void Clear() + { + _lastItemIndex = -1; + } + + // 堆顶是最小值 + private void MinHeapifyUp(int index) + { + if (index == 0) + { + return; + } + + int childIndex = index; + int parentIndex = (index - 1) / 2; + + // 堆顶是最小值 + if (_comparer.Compare(_arr[childIndex], _arr[parentIndex]) < 0) + { + // swap the parent and the child + T temp = _arr[childIndex]; + _arr[childIndex] = _arr[parentIndex]; + _arr[parentIndex] = temp; + + // 递归 + MinHeapifyUp(parentIndex); + } + } + + private void MinHeapifyDown(int index) + { + int leftChildIndex = index * 2 + 1; + int rightChildIndex = index * 2 + 2; + int smallestItemIndex = index; // The index of the parent + + if (leftChildIndex <= _lastItemIndex && + _comparer.Compare(_arr[leftChildIndex], _arr[smallestItemIndex]) < 0) + { + smallestItemIndex = leftChildIndex; + } + + if (rightChildIndex <= _lastItemIndex && + _comparer.Compare(_arr[rightChildIndex], _arr[smallestItemIndex]) < 0) + { + smallestItemIndex = rightChildIndex; + } + + if (smallestItemIndex != index) + { + // swap the parent with the smallest of the child items + T temp = _arr[index]; + _arr[index] = _arr[smallestItemIndex]; + _arr[smallestItemIndex] = temp; + + MinHeapifyDown(smallestItemIndex); + } + } + + private void Resize() + { + T[] newArr = new T[_arr.Length * 2]; + for (int i = 0; i < _arr.Length; i++) + { + newArr[i] = _arr[i]; + } + + _arr = newArr; + } + } +} diff --git a/UnityCollection/Assets/Infrastructure/CollectionExtends/MinHeap.cs.meta b/UnityCollection/Assets/Infrastructure/CollectionExtends/MinHeap.cs.meta new file mode 100644 index 0000000..d06ef93 --- /dev/null +++ b/UnityCollection/Assets/Infrastructure/CollectionExtends/MinHeap.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7957fc1b317c31b4f94f56d48073da22 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: |