0. 简介
普通的队列是一种先进先出的数据结构,元素在队列尾追加,而从队列头删除。在优先队列中,元素被赋予优先级。当访问元素时,具有最高优先级的元素最先删除。优先队列具有最高级先出(first in, largest out)的行为特征。通常采用堆数据结构来实现。
1. 代码实现
本代码采用C#编写,包含优先队列的几种常用操作:
- 入队
- 队首元素
- 出队
- 队列中元素数量
此外,还有一个相应的测试程序,测试算法是否正确。
using System;
using System.Collections.Generic;
namespace DataStructure {
public class PriorityQueue {
// 数组形式的堆
int[] heap = new int[100000];
// 队列中元素的数量
public int Count { get; private set; } = 0;
// 入队
// 将新的元素从树叶 上移 到合适的位置
public void Push(int val) {
heap[++Count] = val;
int cur = Count;
int parent;
while ((parent = Parent(cur)) >= 1 && heap[cur] > heap[parent]) {
Swap(ref heap[cur], ref heap[parent]);
cur = parent;
}
}
// 返回队首元素
// 队首元素位于堆顶,一定是最大的元素
public int Top() {
return heap[1];
}
// 出队
// 弹出堆顶元素,将堆中最后一个元素置于堆顶,然后 下移 到合适的位置
public int Pop() {
int top = heap[1];
heap[1] = heap[Count--];
int cur = 1;
while (true) {
int leftChild = LeftChild(cur);
int rightChild = RightChild(cur);
if (leftChild <= Count && heap[cur] < heap[leftChild] && (rightChild > Count || heap[leftChild] >= heap[rightChild])) {
Swap(ref heap[cur], ref heap[leftChild]);
cur = leftChild;
} else if (rightChild <= Count && heap[cur] < heap[rightChild]) {
Swap(ref heap[cur], ref heap[rightChild]);
cur = rightChild;
} else {
break;
}
}
return top;
}
// 左孩子结点
static int LeftChild(int node) {
return node << 1;
}
// 右孩子结点
static int RightChild(int node) {
return (node << 1) | 1;
}
// 双亲结点
static int Parent(int node) {
return node >> 1;
}
// 交换两个变量
static void Swap<T>(ref T a, ref T b) {
T temp = a;
a = b;
b = temp;
}
}
// 测试类,用于测试算法的正确性
class Test {
static void Main(string[] args) {
PriorityQueue pq = new PriorityQueue();
Random random = new Random();
List<int> list = new List<int>();
while (list.Count <= 10000) {
Console.WriteLine("Count: {0}", list.Count);
int choice = random.Next(0, 4);
if (choice == 0) {
if (list.Count > 0) {
int top1 = list[list.Count - 1];
list.RemoveAt(list.Count - 1);
int top2 = pq.Pop();
if (top1 != top2 || list.Count != pq.Count) {
throw new Exception("Wrong in Pop()!");
}
}
} else if (choice == 1) {
if (list.Count > 0) {
int top1 = list[list.Count - 1];
int top2 = pq.Top();
if (top1 != top2) {
throw new Exception("Wrong in Top()!");
}
}
} else {
int val = random.Next(0, 1000);
list.Add(val);
list.Sort();
pq.Push(val);
if (list.Count != pq.Count) {
throw new Exception("Wrong in Push()!");
}
}
}
while (list.Count > 0) {
Console.WriteLine("Count: {0}", list.Count);
int top1 = list[list.Count - 1];
list.RemoveAt(list.Count - 1);
int top2 = pq.Pop();
if (top1 != top2 || list.Count != pq.Count) {
throw new Exception("Wrong in Pop()!");
}
}
Console.WriteLine("恭喜,您的代码通过了测试!");
}
}
}
本文介绍优先队列的概念及其实现方式,重点讲解如何使用堆数据结构来实现优先队列,包括入队、出队、获取队首元素等基本操作,并提供C#代码示例。
1217

被折叠的 条评论
为什么被折叠?



