知识大全 用 C# 实现带键值的优先队列[2]
Posted 知
篇首语:富贵必从勤苦得,男儿须读五车书。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 用 C# 实现带键值的优先队列[2]相关的知识,希望对你有一定的参考价值。
用 C# 实现带键值的优先队列[2] 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!
上述 KeyedPriorityQueue<T K V> 类中 T 是要存储在这个带键值的优先队列中的数据的类型 K 是键的数据类型 V 是值的数据类型
Dictionary<K int> keys 字段用于存储键(K)在堆(heap)中的索引
bool ContainsKey(K key) 方法用于查找指定的键是否在该优先队列中
Update(T v) 方法用于更新指定项目的值 注意 如果要使用这个方法的话 T 不能是值类型 之所以在这个方法的第二行:
if (typeof(T) IsValueType) throw new InvalidOperationException( T 不能是值类型 );
进行这个判断 而不是在将该类声明为
class KeyedPriorityQueue<T K V> where T : class这是因为 如果不需要调用 Update(T v) 方法的话 T 还是允许是值类型的
该类的其他方面 除了加入对 keys 字段的处理以外 就和标准的优先队列差不多了
有了这个 KeyedPriorityQueue<T K V> 类 就可以从中派生出 PriorityQueue<T> 类来
class PriorityQueue<T> : KeyedPriorityQueue<T object object> public PriorityQueue() : base(null) public PriorityQueue(int capacity) : base(capacity null) public PriorityQueue(IComparer<T> parer) : base(parer null) public PriorityQueue(int capacity IComparer<T> parer) : base(capacity parer null)对于 PriorityQueue<T> 类的实例 如果调用 ContainsKey 方法 总是返回 false 如果调用 Update 方法 总是引发 NotSupportedException 异常
现在让我们回到上一篇随笔 Timus Memory management 中 需要稍微修改一下我们的内存管理器程序
首先 Block 必须从结构改为类 如下所示
sealed class Block public int Id get; private set; public int Time get; set; public Block(int id int time) Id = id; Time = time;然后 需要一个实现 IKeyValue<T K V> 接口的类
sealed class IdTime : IKeyValue<Block int int> public int GetKey(Block x) return x Id; public int GetValue(Block x) return x Time; public void SetValue(Block x int v) x Time = v;最后 就剩下最简单的工作了 将 Main 方法的第二行
var used = new KeyedPriorityQueue(new TimeComparer());修改为
var used = new KeyedPriorityQueue<Block int int>(new TimeComparer() new IdTime());就可以了
当然 这也是有代价的 就是运行时间和内存使用都增加了
ID Date Author Problem Language Judgementresult
Executiontime
Memoryused
: : Apr skyivben C# Accepted KB : : Apr skyivben C# Accepted KB上表中第二行就是上一篇随笔中的程序提交的结果 第一行就是按照本篇随笔修改后的程序提交的结果
实际上 虽然 KeyedPriorityQueue 类中的代码与 PriorityQueue<T> 类中代码有大量的重复 可以用本篇随笔的方法将 KeyedPriorityQueue 类改为 KeyedPriorityQueue<T K V> 泛型类 再从中派生出 PriorityQueue<T> 类来 以消除重复的代码 但是 这样必然造成 PriorityQueue<T> 类的运行效率降低 所以 一般情况下 PriorityQueue<T> 类还是使用原来的代码为好
当然 如果能够从 PriorityQueue<T> 类派生出 KeyedPriorityQueue<T K V> 类 那就比较完美了 不知各位大侠是否还有更好的方法?
cha138/Article/program/net/201311/15448相关参考