Skip to main content
Code Review

Return to Answer

replaced http://stackoverflow.com/ with https://stackoverflow.com/
Source Link

General

Priority queues in general keep a queue per priority. While your implementation achieves that, it is associated with a lot of copying when inserting and removing data due to the array backing structure of List. Using a SortedList with the priority as key and Queue<T> as values would probably be faster and less code.

This question on SO This question on SO shows a basic implementation based on a SortedDictionary.

Technical

  1. For consistency I would consider implementing all three Clear methods with the same interface (returning the number of elements removed) and all go through one method. Something like this:

     public int Clear()
     {
     return Clear(0);
     }
     public int Clear(int startIndex)
     {
     return Clear(startIndex, Count - 1 - startIndex);
     }
     public int Clear(int startIndex, int count)
     {
     // Note: RemoveRange will throw if index and count are not a valid range within the list
     list.RemoveRange(startIndex, count);
     return count;
     }
    
  2. Consider changing PopFront to use an enumerator which avoids creating a temporary copy:

     public IEnumerable<T> PopFront(Int32 numberToPop)
     {
     if (numberToPop > items.Count)
     {
     throw new ArgumentException(@"The numberToPop exceeds the number 
     of elements in the queue", "numberToPop");
     }
     while (numberToPop-- > 0)
     {
     yield return PopFront();
     }
     }
    

Same for PopBack

  1. FindIndexAndInsertItemAscending and FindIndexAndInsertItemDescending are almost exactly the same except for the PriorityConvention passed to FindIndexAndInsertItem so they should be refactored into one method.

Also List defines a BinarySearch method which should simplify your code somewhat. No need to reinvent the wheel.

General

Priority queues in general keep a queue per priority. While your implementation achieves that, it is associated with a lot of copying when inserting and removing data due to the array backing structure of List. Using a SortedList with the priority as key and Queue<T> as values would probably be faster and less code.

This question on SO shows a basic implementation based on a SortedDictionary.

Technical

  1. For consistency I would consider implementing all three Clear methods with the same interface (returning the number of elements removed) and all go through one method. Something like this:

     public int Clear()
     {
     return Clear(0);
     }
     public int Clear(int startIndex)
     {
     return Clear(startIndex, Count - 1 - startIndex);
     }
     public int Clear(int startIndex, int count)
     {
     // Note: RemoveRange will throw if index and count are not a valid range within the list
     list.RemoveRange(startIndex, count);
     return count;
     }
    
  2. Consider changing PopFront to use an enumerator which avoids creating a temporary copy:

     public IEnumerable<T> PopFront(Int32 numberToPop)
     {
     if (numberToPop > items.Count)
     {
     throw new ArgumentException(@"The numberToPop exceeds the number 
     of elements in the queue", "numberToPop");
     }
     while (numberToPop-- > 0)
     {
     yield return PopFront();
     }
     }
    

Same for PopBack

  1. FindIndexAndInsertItemAscending and FindIndexAndInsertItemDescending are almost exactly the same except for the PriorityConvention passed to FindIndexAndInsertItem so they should be refactored into one method.

Also List defines a BinarySearch method which should simplify your code somewhat. No need to reinvent the wheel.

General

Priority queues in general keep a queue per priority. While your implementation achieves that, it is associated with a lot of copying when inserting and removing data due to the array backing structure of List. Using a SortedList with the priority as key and Queue<T> as values would probably be faster and less code.

This question on SO shows a basic implementation based on a SortedDictionary.

Technical

  1. For consistency I would consider implementing all three Clear methods with the same interface (returning the number of elements removed) and all go through one method. Something like this:

     public int Clear()
     {
     return Clear(0);
     }
     public int Clear(int startIndex)
     {
     return Clear(startIndex, Count - 1 - startIndex);
     }
     public int Clear(int startIndex, int count)
     {
     // Note: RemoveRange will throw if index and count are not a valid range within the list
     list.RemoveRange(startIndex, count);
     return count;
     }
    
  2. Consider changing PopFront to use an enumerator which avoids creating a temporary copy:

     public IEnumerable<T> PopFront(Int32 numberToPop)
     {
     if (numberToPop > items.Count)
     {
     throw new ArgumentException(@"The numberToPop exceeds the number 
     of elements in the queue", "numberToPop");
     }
     while (numberToPop-- > 0)
     {
     yield return PopFront();
     }
     }
    

Same for PopBack

  1. FindIndexAndInsertItemAscending and FindIndexAndInsertItemDescending are almost exactly the same except for the PriorityConvention passed to FindIndexAndInsertItem so they should be refactored into one method.

Also List defines a BinarySearch method which should simplify your code somewhat. No need to reinvent the wheel.

Source Link
ChrisWue
  • 20.6k
  • 4
  • 43
  • 107

General

Priority queues in general keep a queue per priority. While your implementation achieves that, it is associated with a lot of copying when inserting and removing data due to the array backing structure of List. Using a SortedList with the priority as key and Queue<T> as values would probably be faster and less code.

This question on SO shows a basic implementation based on a SortedDictionary.

Technical

  1. For consistency I would consider implementing all three Clear methods with the same interface (returning the number of elements removed) and all go through one method. Something like this:

     public int Clear()
     {
     return Clear(0);
     }
     public int Clear(int startIndex)
     {
     return Clear(startIndex, Count - 1 - startIndex);
     }
     public int Clear(int startIndex, int count)
     {
     // Note: RemoveRange will throw if index and count are not a valid range within the list
     list.RemoveRange(startIndex, count);
     return count;
     }
    
  2. Consider changing PopFront to use an enumerator which avoids creating a temporary copy:

     public IEnumerable<T> PopFront(Int32 numberToPop)
     {
     if (numberToPop > items.Count)
     {
     throw new ArgumentException(@"The numberToPop exceeds the number 
     of elements in the queue", "numberToPop");
     }
     while (numberToPop-- > 0)
     {
     yield return PopFront();
     }
     }
    

Same for PopBack

  1. FindIndexAndInsertItemAscending and FindIndexAndInsertItemDescending are almost exactly the same except for the PriorityConvention passed to FindIndexAndInsertItem so they should be refactored into one method.

Also List defines a BinarySearch method which should simplify your code somewhat. No need to reinvent the wheel.

lang-cs

AltStyle によって変換されたページ (->オリジナル) /