C# 中的优先队列( PriorityQueue<TElement, TPriority> )是按优先级排序的数据结构,优先级高的元素会被优先取出,底层通过最小堆实现,需引用  System.Collections.Generic  命名空间(.NET 6+ 正式引入)。


一、核心特性与原理
 
1. 优先级驱动:元素入队时需关联一个优先级(如 int、double 等可比较类型),出队时始终取出优先级最高(默认最小优先级值视为最高)的元素,而非按入队顺序。
2. 底层实现:基于最小堆(一种完全二叉树),确保每次获取/移除优先级最高的元素时,时间复杂度仅为 O(log n),效率远高于普通队列排序。
3. 优先级规则:默认使用  IComparer<TPriority>  比较优先级,如 int 类型中, 1  的优先级高于  2 ;可自定义比较器修改规则(如让大值优先级更高)。
 
二、典型应用场景
 
- 任务调度:如操作系统中高优先级进程优先执行、游戏中紧急事件(如角色死亡)优先处理。
- 最短路径算法:如 Dijkstra 算法,优先选择当前距离起点最近的节点。
- 事件驱动系统:如日志系统中,错误日志(高优先级)比信息日志(低优先级)优先输出。
 
三、核心方法与代码示例
 
1. 常用方法
 
方法名 功能描述 

  •  Enqueue  向队列中添加元素及对应的优先级 
  •  Dequeue  移除并返回优先级最高的元素(队首) 
  •  Peek  仅返回(不移除)优先级最高的元素 
  •  TryDequeue  尝试移除并返回最高优先级元素,返回是否成功 
  •  Count  获取队列中元素的总数 
  •  Clear  清空队列中所有元素 

 
2. 基础示例:模拟任务调度
 
需求:3个任务分别标注优先级(1=紧急,3=普通),让紧急任务优先执行。

 
using System;
using System.Collections.Generic;

class PriorityQueueDemo
{
    static void Main()
    {
        // 定义优先队列:TElement=任务名称(string),TPriority=优先级(int)
        PriorityQueue<string, int> taskQueue = new PriorityQueue<string, int>();

        // 1. 入队:添加任务及优先级(1=最高,3=最低)
        taskQueue.Enqueue("生成用户报表(普通)", 3);
        taskQueue.Enqueue("修复支付bug(紧急)", 1);
        taskQueue.Enqueue("同步数据库数据(一般)", 2);

        Console.WriteLine($"任务总数:{taskQueue.Count}\n"); // 输出:3

        // 2. 出队:按优先级从高到低执行任务
        while (taskQueue.Count > 0)
        {
            // 取出优先级最高的任务
            string currentTask = taskQueue.Dequeue();
            Console.WriteLine($"正在执行:{currentTask}");
        }
    }
}

// 输出结果(优先级1最先,3最后):
// 任务总数:3
// 正在执行:修复支付bug(紧急)
// 正在执行:同步数据库数据(一般)
// 正在执行:生成用户报表(普通)


 
3. 进阶示例:自定义优先级规则
 
需求:让数值大的优先级更高(如优先级 3 比 1 先执行),需自定义  IComparer<int> 。
 


using System;
using System.Collections.Generic;

// 自定义比较器:反转默认规则,大值优先级更高
class ReversePriorityComparer : IComparer<int>
{
    public int Compare(int x, int y)
    {
        // 默认 Compare(x,y) 返回负数时 x 优先级高,此处反转,让 y 比 x 小则 x 优先级高
        return y.CompareTo(x);
    }
}

class CustomPriorityDemo
{
    static void Main()
    {
        // 初始化队列时传入自定义比较器
        PriorityQueue<string, int> queue = new PriorityQueue<string, int>(new ReversePriorityComparer());
        
        queue.Enqueue("任务A", 1);
        queue.Enqueue("任务B", 3);
        queue.Enqueue("任务C", 2);

        // 出队顺序:3(B)→2(C)→1(A)
        while (queue.Count > 0)
        {
            Console.WriteLine(queue.Dequeue()); // 输出:任务B → 任务C → 任务A
        }
    }
}


四、注意事项
 
1. 优先级类型必须可比较: TPriority  必须实现  IComparable<TPriority>  接口,否则需在初始化时传入自定义  IComparer<TPriority> ,否则会报错。
2. 相同优先级的元素:当多个元素优先级相同时,按入队顺序出队(底层堆结构保证先进先出)。
3. 空值处理: TElement  允许为  null (引用类型),但  TPriority  不允许为  null ,否则会抛出  ArgumentNullException 。

Next: C#利用优先队列实现Dijkstra算法和订单业务场景算法

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐