大数跨境
0
0

.NET 9 Preview 1 PriorityQueue 更新

.NET 9 Preview 1 PriorityQueue 更新 amazingdotnet
2024-02-18
1
导读:.NET 9 PriorityQueue Remove

.NET 9 Preview 1 PriorityQueue 更新

Intro

.NET 6 开始内置了一个 PriorityQueue,之前有写过一篇介绍文章,可以参考:.NET6 中的 PriorityQueue

.NET 9 新增了 Remove 方法来移除 queue 里的某一个元素

Sample

新增 API 定义如下:

public bool Remove(TElement element, out TElement removedElement, out TPriority priority, IEqualityComparer<TElement>? equalityComparer = null);

我们可以通过 Remove 方法的返回值来判断是否移除成功

var queue = new PriorityQueue<stringint>();

queue.Enqueue("Lily"88);
queue.Enqueue("Ming"80);
queue.Enqueue("Alice"90);
queue.Enqueue("Mike"85);
queue.Enqueue("Amy"99);
queue.Enqueue("Alex"98);

if (!queue.Remove("Jane"out _, out _))
{
    Console.WriteLine("Jane not existed");
}

if (queue.Remove("Alice"out _, out _))
{
    Console.WriteLine("Alice removed");
}

Remove 的时候可以提供一个自定义的相等性比较,所以我们也可以使用自定义的比较器来 override 默认的,例如:

if (!queue.Remove("mike"out _, out _))
{
    Console.WriteLine($"mike not exists");
}

if (queue.Remove("mike"out var removedElement, out var removedPriority, StringComparer.OrdinalIgnoreCase))
{
    Console.WriteLine($"RemovedElement - {removedElement}{removedPriority}");
}

借助于此我们也可以变相地实现 Update 的功能

if (queue.Remove("alex"out removedElement, out removedPriority, StringComparer.OrdinalIgnoreCase))
{
    queue.Enqueue(removedElement, 60);
    Console.WriteLine($"Element priority updated: {removedElement}, previous priority: {removedPriority}, new priority: {60}");
}

使用得比较多可以封装一个扩展方法

public static void EnqueueOrUpdate<TElement, TPriority>(this PriorityQueue<TElement, TPriority> queue, TElement element, TPriority priority)
{
    queue.Remove(element, out _, out _);
    queue.Enqueue(element, priority);
}

完整的示例如下:

var queue = new PriorityQueue<stringint>();

queue.Enqueue("Lily"88);
queue.Enqueue("Ming"80);
queue.Enqueue("Alice"90);
queue.Enqueue("Mike"85);
queue.Enqueue("Amy"99);
queue.Enqueue("Alex"98);

if (!queue.Remove("Jane"out _, out _))
{
    Console.WriteLine("Jane not existed");
}        
if (queue.Remove("Alice"out _, out _))
{
    Console.WriteLine("Alice removed");
}        

Console.WriteLine();
// remove with custom equality comparer
if (!queue.Remove("mike"out _, out _))
{
    Console.WriteLine($"mike not exists");
}
if (queue.Remove("mike"out var removedElement, out var removedPriority, StringComparer.OrdinalIgnoreCase))
{
    Console.WriteLine($"RemovedElement - {removedElement}{removedPriority}");
}

// update priority
if (queue.Remove("alex"out removedElement, out removedPriority, StringComparer.OrdinalIgnoreCase))
{
    queue.Enqueue(removedElement, 60);
    Console.WriteLine($"Element priority updated: {removedElement}, previous priority: {removedPriority}, new priority: {60}");
}

Console.WriteLine();
Console.WriteLine("PriorityQueue elements:");
while (queue.TryDequeue(out var element, out var priority))
{
    Console.WriteLine($"{element}{priority}");
}

Console.WriteLine();

输出结果如下

output

More

目前还没 UpdatePriority 之类的方法,如果你需要也可以在这个 issue 上进行反馈

https://github.com/dotnet/runtime/issues/44871

基于 Remove 方法,PR 还提供了一个简单的 Dijkstra 最短路径算法的示例,有需要可以查看 https://github.com/dotnet/runtime/pull/93994/files#diff-4af9482a6250d6c44d2ee4c349fa4c3f97b977e4980e8cdb594ab8c481e9e352R18

References

  • https://github.com/dotnet/runtime/issues/44871
  • https://github.com/dotnet/runtime/issues/93925
  • https://github.com/dotnet/runtime/pull/93994
  • https://github.com/WeihanLi/SamplesInPractice/blob/main/net9sample/Net9Samples/PriorityQueueSample.cs
  • https://www.freecodecamp.org/chinese/news/dijkstras-shortest-path-algorithm-visual-introduction/
  • .NET6 中的 PriorityQueue


【声明】内容源于网络
0
0
amazingdotnet
dotnet 开发知识库,了不起的 dotnet,dotnet 奇淫怪巧
内容 539
粉丝 0
amazingdotnet dotnet 开发知识库,了不起的 dotnet,dotnet 奇淫怪巧
总阅读27
粉丝0
内容539