C# 中的 PriorityQueue 类是一个基于优先级的队列数据结构,它允许用户根据元素的优先级对元素进行排序。PriorityQueue 内部使用了一个最小堆(Min Heap)来实现这个功能。下面是 PriorityQueue 的实现细节:
数据结构:PriorityQueue 内部使用了一个数组(Array)来存储元素,以及一个整数(int)类型的变量来表示当前队列中的元素数量(count)。
排序规则:PriorityQueue 的排序规则是按照元素的优先级进行排序。在最小堆中,父节点的优先级总是小于或等于其子节点的优先级。因此,最小堆的根节点总是具有最小的优先级值。
插入操作:当向 PriorityQueue 中插入一个新元素时,首先将新元素添加到数组的末尾。然后,从数组的末尾开始,向上遍历数组,找到第一个优先级大于新元素的节点。将新元素插入到这个位置,并向上移动这个节点,直到满足堆的性质。
删除操作:PriorityQueue 的删除操作实际上是获取并移除优先级最高的元素(即最小堆的根节点)。为了保持堆的性质,需要将根节点的子节点中优先级最小的节点移到根节点,并向上移动这个节点,直到满足堆的性质。最后,将数组末尾的元素移除。
查找操作:PriorityQueue 不支持直接查找特定元素。如果需要查找特定元素,可以使用其他数据结构(如 Dictionary 或 HashSet)来存储元素及其优先级,然后在 PriorityQueue 中插入这些键值对。
示例代码:
using System;
class PriorityQueue
{
private int[] elements;
private int count;
public PriorityQueue(int capacity)
{
elements = new int[capacity];
count = 0;
}
public void Insert(int value)
{
elements[count++] = value;
int parentIndex = (count - 1) / 2;
while (parentIndex >= 0 && elements[parentIndex] > elements[count - 1])
{
int temp = elements[parentIndex];
elements[parentIndex] = elements[count - 1];
elements[count - 1] = temp;
count = parentIndex;
parentIndex = (count - 1) / 2;
}
}
public int Remove()
{
if (count == 0)
throw new InvalidOperationException("PriorityQueue is empty.");
int minValue = elements[0];
elements[0] = elements[--count];
int childIndex = 0;
while (true)
{
int leftChildIndex = 2 * childIndex + 1;
int rightChildIndex = 2 * childIndex + 2;
int smallestChildIndex = -1;
if (leftChildIndex < count && elements[leftChildIndex] < elements[smallestChildIndex])
smallestChildIndex = leftChildIndex;
if (rightChildIndex < count && elements[rightChildIndex] < elements[smallestChildIndex])
smallestChildIndex = rightChildIndex;
if (smallestChildIndex == -1)
break;
int temp = elements[smallestChildIndex];
elements[smallestChildIndex] = elements[count];
elements[count] = temp;
count = smallestChildIndex;
childIndex = (childIndex * 2) + 1;
}
return minValue;
}
}
这个示例代码实现了一个简单的 PriorityQueue 类,支持插入和删除操作。请注意,这个实现不是线程安全的,如果在多线程环境中使用,需要进行适当的同步处理。