2010-09-04 33 views
1

最近寫了一些數據結構作爲自己的審查。我想知道是否有人對下面的代碼有一些反饋,也許更好,更快的方法?更好的方式來實現或反饋這個C#最大堆優先級隊列

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using Microsoft.VisualStudio.TestTools.UnitTesting; 
namespace MaxHeapPriorityQueue 
{ 
    public class PriorityItem<T> 
    { 
     public T Data { get; set; } 
     public int Priority { get; set; } 
     public PriorityItem(T data, int priority) 
     { 
      Data = data; 
      Priority = priority; 
     } 

     public string ToString() 
     { 
      return Priority.ToString(); 
     } 
    } 

    public class PriorityQueue<T> 
    { 
     private List<PriorityItem<T>> array; 
     public PriorityQueue() 
     { 
      array = new List<PriorityItem<T>>(); 
     } 

     public void enqueue(T data, int priority) 
     { 
      PriorityItem<T> item = new PriorityItem<T>(data, priority); 
      array.Add(item); 
      MaxHeapify(); 
     } 

     public T dequeue() 
     { 
      T max = array[0].Data; 
      array.RemoveAt(0); 
      MaxHeapify(); 
      return max; 
     } 

     public void MaxHeapify() 
     { 
      //children must be less than the parent 
      //left = 2i-1 
      //right = 2i 
      for (int i = 0; i < array.Count; i++) 
      { 
       int leftPos = CalcLeft(i); 
       int rightPos = CalcRight(i); 
       int leftPriority = 0; 
       int rightPriority = 0; 

       if (leftPos !=-1) 
        leftPriority = array[leftPos].Priority; 

       if (rightPos !=-1) 
        rightPriority = array[rightPos].Priority; 

       //swap with parents where applicable 
       int highestPriority = 0; 
       if (leftPriority > array[i].Priority) 
       { 
        highestPriority = leftPriority; 
       } 
       else 
       if (rightPriority > array[i].Priority && rightPriority > leftPriority) 
       { 
        highestPriority = rightPriority; 
       } 

       //swap 
       PriorityItem<T> temp; 
       temp = array[i]; 
       if (highestPriority == leftPriority && leftPos != -1) 
       {      
        array[i] = array[leftPos]; 
        array[leftPos] = temp; 
       } 
       else if (highestPriority == rightPriority && rightPos!=-1) 
       { 
        array[i] = array[rightPos]; 
        array[rightPos] = temp; 
       } 
      } 

     } 

     int CalcLeft(int i) 
     { 
      i++; 
      if ((2 * i)-1 < array.Count) 
       return (2 * i) -1; 
      else 
       return -1; 
     } 

     int CalcRight(int i) 
     { 
      i++; 
      if ((2 * i) < array.Count) 
      { 
       return (2 * i); 
      } 
      else 
      { 
       return -1; 
      } 
     } 

    } 


    class Program 
    { 
     static void Main(string[] args) 
     { 
      PriorityQueue<string> pq = new PriorityQueue<string>(); 

      pq.enqueue("a", 1); 
      pq.enqueue("b", 2); 
      pq.enqueue("c", 4); 
      pq.enqueue("e", 5); 
      pq.enqueue("d", 3); 

      string val = pq.dequeue(); 
      Assert.AreEqual("e", val); 
      val = pq.dequeue(); 
      Assert.AreEqual("c", val); 
      val = pq.dequeue(); 
      Assert.AreEqual("d", val); 

      pq.enqueue("e", 10); 

      val = pq.dequeue(); 
      Assert.AreEqual("e", val); 
      val = pq.dequeue(); 
      Assert.AreEqual("b", val); 
      val = pq.dequeue(); 
      Assert.AreEqual("a", val); 

     } 
    } 
} 
+0

噢,除了使用數組。這是下一步。 – j03m 2010-09-04 00:08:59

+0

我無法得到這個工作以下場景'pq.enqueue(「a」,1); pq.enqueue(「b」,2); pq.enqueue(「c」,3); pq.enqueue(「e」,4); pq.enqueue(「d」,5); ' – Confused 2011-10-13 19:10:40

回答

1

我想讓您的PriorityItem爲IComparable。然後,您可以繼續整數優先級,或者你可以去稍微更奇特:

public class PriorityItem<DataType, ComparerType> : IComparable<PriorityItem<DataType, ComparerType>> 
    where ComparerType : IComparable 
{ 
    public DataType Data { get; set; } 
    public ComparerType Priority { get; set; } 

    public PriorityItem(DataType data, ComparerType priority) 
    { 
     Data = data; 
     Priority = priority; 
    } 

    public string ToString() 
    { 
     return Priority.ToString(); 
    } 

    public int CompareTo(PriorityItem<DataType, ComparerType> other) 
    { 
     if (other == null) return 1; 
     return Priority.CompareTo(other.Priority); 
    } 

    public int CompareTo(object other) 
    { 
     return CompareTo(other as PriorityItem<DataType, ComparerType>); 
    } 
} 

public class PriorityItem<DataAndComparerType> : PriorityItem<DataAndComparerType, DataAndComparerType> 
    where ComparerType : IComparable 
{ 
    public PriorityItem(DataAndComparerType data) : base(data, data) 
    { 
    } 
} 

這會給你的選項非常好的陣列使用PriorityItem(使用數據所在的位置數據和比較器,或提供一個自定義比較,或使用PriorityItem提供一個int)。這會使MaxHeapify大約只有一半。它也允許你使用一個標準的排序後備存儲(如SortedList),它將完全取消對MaxHeapify的需求,儘管這需要你的Priority屬性有一個私有setter。