实现了支持泛型的优先队列,解决Unity官方不提供优先队列的问题。
API
属性和字段 | 解释 |
---|
size | 队列的长度 |
capacity | 队列的容量 |
IsEmpty | 返回队列是否为空 |
Top | 返回队列第一个元素 |
枚举 | 解释 |
---|
PriorityQueueMode.less | 最小优先队列 |
PriorityQueueMode.equal | 只会将相等的排在一起 |
PriorityQueueMode.greator | 最大优先队列 |
函数 | 功能 |
---|
Push | 入队一个元素 |
Pop | 出队一个元素 |
Peek | 返回第一个元素 |
Clear | 清空队列 |
示例
PriorityQueue<int> priorityQueue = new PriorityQueue<int>((a, b) => {if (a < b) return -1;else if (a == b) return 0;else if (a > b) return 1;return 0;
});priorityQueue.Push(8);
priorityQueue.Push(9);
priorityQueue.Push(3);
priorityQueue.Push(2);
priorityQueue.Push(7);
priorityQueue.Push(5);
priorityQueue.Push(0);while (!priorityQueue.IsEmpty) {Debug.Log(priorityQueue.Top);priorityQueue.Pop();
}
实现
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;namespace YBZ.Algorithm {public class PriorityQueue<T> where T : new (){public int size;public int capacity;private T[] elements;public bool IsEmpty { get => size == 0; }public T Top { get => elements[0]; }private PriorityQueueMode _comparator;public enum PriorityQueueMode {less = -1, equal = 0, greater = 1 }private Func<T,T,int> CMP;public PriorityQueue(Func<T,T,int> CMP, PriorityQueueMode priorityQueueMode = PriorityQueueMode.less, int capacity = 1) {this.CMP = CMP;this.size = 0; this.capacity = capacity;this.elements = new T[capacity];this._comparator = priorityQueueMode;}public void Push(T value) {if (size == capacity) {ExpandCapacity();}elements[size++] = value;ShiftUp();}public void Pop() {if(size == 0) {return;}size--;Swap(ref elements[0], ref elements[size]);ShiftDown();}public void Clear() {size = 0;}public T Peek() {return Top;}private void ExpandCapacity() {capacity = Mathf.CeilToInt(capacity * 1.5f);T[] temp = new T[capacity];for (int i = 0; i < elements.Length; i++) {temp[i] = elements[i];}elements = temp;}private void ShiftUp() {int cur = size - 1 ;int parent = ( cur -1 ) >> 2;while (cur > 0) {if (CMP(elements[cur],elements[parent]) == (int)_comparator) {Swap(ref elements[cur], ref elements[parent]);cur = parent;parent = (cur - 1) >> 2;} else break;}}private void ShiftDown() {int cur = 0;int child = 1;while (child < size) {if (child + 1 < size && CMP(elements[child +1], elements[child]) == (int)_comparator) {child++;}if (CMP(elements[child], elements[cur]) == (int)_comparator){Swap(ref elements[child], ref elements[cur]);cur = child;child = cur << 1 + 1;} else break;}}private void Swap(ref T lhs,ref T rhs) {T temp = lhs;lhs = rhs;rhs = temp;}public override string ToString() {string result = "";foreach (var v in elements) {result += v.ToString();}return result;}}
}