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 類,支持插入和刪除操作。請注意,這個實現不是線程安全的,如果在多線程環境中使用,需要進行適當的同步處理。