知识大全 用 C# 实现带键值的优先队列[1]
Posted 类型
篇首语:惜时专心苦读是做学问的一个好方法。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 用 C# 实现带键值的优先队列[1]相关的知识,希望对你有一定的参考价值。
用 C# 实现带键值的优先队列[1] 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!
首先 需要一个接口 用来获取键以及获取和设置值 如下所示
namespace Skyiv Util interface IKeyValue<T K V> K GetKey(T x); V GetValue(T x); void SetValue(T x V v);接着 就是我们的带键值的优先队列 KeyedPriorityQueue<T K V> 登场了
using System;using System Collections Generic;
namespace Skyiv Util class KeyedPriorityQueue<T K V> IComparer<T> parer; IKeyValue<T K V> kver; Dictionary<K int> keys; bool hasKey; T[] heap;
public int Count get; private set; public KeyedPriorityQueue(IKeyValue<T K V> kv) : this(null kv) public KeyedPriorityQueue(int capacity IKeyValue<T K V> kv) : this(capacity null kv) public KeyedPriorityQueue(IComparer<T> parer IKeyValue<T K V> kv) : this( parer kv)
public KeyedPriorityQueue(int capacity IComparer<T> parer IKeyValue<T K V> kver) this keys = new Dictionary<K int>(); this parer = (parer == null) ? Comparer<T> Default : parer; this kver = kver; this hasKey = (kver != null); this heap = new T[capacity];
public bool ContainsKey(K key) return keys ContainsKey(key);
public void Update(T v) if (!hasKey) throw new NotSupportedException(); if (typeof(T) IsValueType) throw new InvalidOperationException( T 不能是值类型 ); if (!ContainsKey(kver GetKey(v))) throw new ArgumentOutOfRangeException( v v 更新优先队列时无此健值 ); var id = keys[kver GetKey(v)]; var cmp = parer Compare(v heap[id]); kver SetValue(heap[id] kver GetValue(v)); // 注意: 这一句要求 T 是引用类型 不能是值类型 if (cmp < ) SiftDown(id); else if (cmp > ) SiftUp(id);
public void Push(T v) if (Count >= heap Length) Array Resize(ref heap Count * ); if (hasKey) keys[kver GetKey(v)] = Count; heap[Count] = v; SiftUp(Count++);
public T Pop() var v = Top(); if (hasKey) keys Remove(kver GetKey(v)); heap[ ] = heap[ Count]; if (Count > ) SiftDown(hasKey ? (keys[kver GetKey(heap[ ])] = ) : ); return v;
public T Top() if (Count > ) return heap[ ]; throw new InvalidOperationException( 优先队列为空 );
void SiftUp(int n) var v = heap[n]; for (var n = n / ; n > && parer Compare(v heap[n ]) > ; n = n n /= ) heap[hasKey ? (keys[kver GetKey(heap[n ])] = n) : n] = heap[n ]; heap[hasKey ? (keys[kver GetKey(v)] = n) : n] = v;
void SiftDown(int n) var v = heap[n]; for (var n = n * ; n < Count; n = n n *= ) if (n + < Count && parer Compare(heap[n + ] heap[n ]) > ) n ++; if (parer Compare(v heap[n ]) >= ) break; heap[hasKey ? (keys[kver GetKey(heap[n ])] = n) : n] = heap[n ]; heap[hasKey ? (keys[kver GetKey(v)] = n) : n] = v;
cha138/Article/program/net/201311/15449相关参考