2009-01-09 46 views
14

Có bất kỳ triển khai cấu trúc dữ liệu heap nào ở đó, mã, nhị phân hoặc nhị thức không?Dãy Fibonacci, nhị phân, hoặc nhị thức trong C#?

Tham chiếu: Đây là những cấu trúc dữ liệu được sử dụng để triển khai hàng đợi ưu tiên, chứ không phải các cấu trúc được sử dụng để cấp phát bộ nhớ động. Xem http://en.wikipedia.org/wiki/Heap_(data_structure)

Cảm ơn, Dave

+0

Chỉ cần tò mò, những gì bạn đang viết một đống gì? – core

+0

http://stackoverflow.com/a/13776636/67824 –

+0

Xem thêm https://stackoverflow.com/questions/102398/priority-queue-in-net –

Trả lời

2

Tôi không biết về bất kỳ thực hiện khuôn khổ bản xứ.

Tôi đã tìm thấy hai hiện thực của đống nhị phân (link 1, link 2) và một triển khai thực hiện đống nhị thức trong f # (link).

5

QuickGraph thực hiện Fibonacci Heaps và Queues trong C#, trong một tổng thể nhiều thứ khác. Nó là miễn phí và mã nguồn mở.

+0

Tài liệu cho QuickGraph rất khó phân tích nếu bạn chỉ tìm kiếm một đoạn mã fib. Mã nguồn cũng không rõ ràng. :( – MushinNoShin

2

Tôi tin rằng một SortedSet<KeyValuePair<K,V>> với một tuỳ chỉnh Comparer sẽ thực hiện công việc.

Các Comparer sẽ trông giống như sau:

class KeyValueComparer<K, V> : IComparer<KeyValuePair<K,V>> where K:IComparable where V:IComparable 
{ 
    public int Compare(KeyValuePair<K, V> x, KeyValuePair<K, V> y) 
    { 
     var res = x.Key.CompareTo(y.Key); 
     return res == 0 ? x.Value.CompareTo(y.Value) : res; 
    } 
} 

Với ví dụ Comparer, các SortedSet sẽ được sắp xếp theo Key và nó sẽ cho phép các bản sao của các phím.

Bạn có thể lấy Min lúc liên tục, RemoveMin tại O(logn), Add một mục tại O(logn)Update một chìa khóa tại O(logn).

Đây là một đầy đủ (hoặc hầu hết) thực hiện:

public class Heap<K, V> 
    where K : IComparable 
    where V : IComparable 
{ 
    private readonly SortedSet<KeyValuePair<K, V>> _sortedSet; 

    // O(1) 
    public KeyValuePair<K, V> Min 
    { 
     get { return _sortedSet.Min; } 
    } 

    public Heap() 
    { 
     _sortedSet = new SortedSet<KeyValuePair<K, V>>(new KeyValueComparer<K, V>()); 
    } 

    // O(logn) 
    public void Add(K key, V value) 
    { 
     _sortedSet.Add(new KeyValuePair<K, V>(key, value)); 
    } 

    // O(logn) 
    public KeyValuePair<K, V> RemoveMin() 
    { 
     var min = Min; 
     _sortedSet.Remove(min); 
     return min; 
    } 

    // O(logn) 
    public void Remove(K key, V value) 
    { 
     _sortedSet.Remove(new KeyValuePair<K, V>(key, value)); 
    } 

    // O(logn) 
    public void UpdateKey(K oldKey, V oldValue, K newKey) 
    { 
     Remove(oldKey, oldValue); 
     Add(newKey, oldValue); 
    } 

    private class KeyValueComparer<K, V> : IComparer<KeyValuePair<K, V>> 
     where K : IComparable 
     where V : IComparable 
    { 
     public int Compare(KeyValuePair<K, V> x, KeyValuePair<K, V> y) 
     { 
      var res = x.Key.CompareTo(y.Key); 
      return res == 0 ? x.Value.CompareTo(y.Value) : res; 
     } 
    } 
} 
0

A Simple Min Heap thực hiện.

https://github.com/bharathkumarms/AlgorithmsMadeEasy/blob/master/AlgorithmsMadeEasy/MinHeap.cs

using System; 
using System.Collections.Generic; 
using System.Linq; 

namespace AlgorithmsMadeEasy 
{ 
    public class MinHeap 
    { 
     private static int capacity = 10; 
     private int size = 0; 

     int[] items = new int[capacity]; 

     private int getLeftChildIndex(int parentIndex) { return 2*parentIndex+1 ; } 
     private int getRightChildIndex(int parentIndex) { return 2*parentIndex+2 ; } 
     private int getParentIndex(int childIndex) { return (childIndex - 1)/2; } 

     private bool hasLeftChild(int index) { return getLeftChildIndex(index) < size; } 
     private bool hasRightChild(int index) { return getRightChildIndex(index) < this.size; } 
     private bool hasParent(int index) { return getParentIndex(index) >= 0; } 

     private int leftChild(int index) { return this.items[getLeftChildIndex(index)]; } 
     private int rightChild(int index) { return this.items[getRightChildIndex(index)]; } 
     private int parent(int index) { return this.items[this.getParentIndex(index)]; } 

     private void swap(int indexOne, int indexTwo) 
     { 
      int temp = this.items[indexOne]; 
      this.items[indexOne] = this.items[indexTwo]; 
      this.items[indexTwo] = temp; 
     } 

     private void ensureExtraCapacity() 
     { 
      if (this.size == capacity) 
      { 
       Array.Resize(ref this.items, capacity*2); 
       capacity *= 2; 
      } 
     } 

     public int peek() 
     { 
      if(this.size==0) throw new NotSupportedException(); 
      return this.items[0]; 
     } 

     public int remove() 
     { 
      if(this.size==0) throw new NotSupportedException(); 
      int item = this.items[0]; 
      items[0] = items[this.size - 1]; 
      items[this.size - 1] = 0; 
      this.size--; 
      heapifyDown(); 
      return item; 
     } 

     public void Add(int item) 
     { 
      this.ensureExtraCapacity(); 
      this.items[size] = item; 
      this.size++; 
      heapifyUp(); 
     } 

     private void heapifyUp() 
     { 
      int index = this.size - 1; 
      while (hasParent(index) && parent(index) > this.items[index]) 
      { 
       swap(index,getParentIndex(index)); 
       index = getParentIndex(index); 
      } 
     } 

     private void heapifyDown() 
     { 
      int index = 0; 
      while (hasLeftChild(index)) 
      { 
       int smallerChildIndex = getLeftChildIndex(index); 
       if (hasRightChild(index) && rightChild(index) < leftChild(index)) 
       { 
        smallerChildIndex = getRightChildIndex(index); 
       } 

       if (this.items[index] < this.items[smallerChildIndex]) 
       { 
        break; 
       } 
       else 
       { 
        swap(index,smallerChildIndex); 
       } 
       index = smallerChildIndex; 
      } 
     } 
    } 
} 

/* 
Calling Code: 
    MinHeap mh = new MinHeap(); 
    mh.Add(10); 
    mh.Add(5); 
    mh.Add(2); 
    mh.Add(1); 
    mh.Add(50); 
    int peek = mh.peek(); 
    mh.remove(); 
    int newPeek = mh.peek(); 
*/ 
3

Đứng một mình căng thẳng triển khai thử nghiệm đang trong Github dưới Advanced-Algorithms kho. Hiệu suất hoạt động DecrementKey là những gì làm cho hai sau đáng kể.

Các kho có hai triển khai đống hơn, D-Ary Heap & Ghép cặp.

0

Thực hiện MinHeap và MaxHeap:

public abstract class Heap<T> 
{ 
    private List<T> m_Vector; 

    private void Swap(int i, int j) 
    { 
     var tmp = m_Vector[i]; 
     m_Vector[i] = m_Vector[j]; 
     m_Vector[j] = tmp; 
    } 

    protected abstract int Compare(T a, T b); 

    private void SiftUp(int i) 
    { 
     if (i == 0) 
     { 
      return; 
     } 

     int parent = (i - 1)/2; 

     if (Compare(m_Vector[i], m_Vector[parent]) >= 0) 
     { 
      return; 
     } 

     Swap(i, parent); 
     SiftUp(parent); 
    } 

    private void SiftDown(int i) 
    { 
     int left = i * 2 + 1; 

     if (left >= m_Vector.Count) 
     { 
      return; 
     } 

     var right = left + 1; 

     var child = left; 

     if (right < m_Vector.Count) 
     { 
      if (Compare(m_Vector[left], m_Vector[right]) > 0) 
      { 
       child = right; 
      } 
     } 

     if (Compare(m_Vector[i], m_Vector[child]) <= 0) 
     { 
      return; 
     } 

     Swap(i, child); 
     SiftDown(child); 
    } 

    public Heap() 
    { 
     m_Vector = new List<T>(); 
    } 

    public Heap(IEnumerable<T> elements) 
    { 
     m_Vector = new List<T>(elements); 

     if (m_Vector.Count < 2) 
     { 
      return; 
     } 

     // 
     // From the last parent, upwards, sift down. Each sift is O<1>. 
     // 
     for (int i = (m_Vector.Count - 2)/2; i >= 0; i--) 
     { 
      SiftDown(i); 
     } 
    } 

    public int Count { get { return m_Vector.Count; } } 

    public void Add(T element) 
    { 
     m_Vector.Add(element); 
     SiftUp(m_Vector.Count - 1); 
    } 

    public T Top 
    { 
     get 
     { 
      if (m_Vector.Count == 0) 
      { 
       throw new InvalidOperationException(); 
      } 
      return m_Vector[0]; 
     } 
    } 

    public T Fetch() 
    { 
     if (m_Vector.Count == 0) 
     { 
      throw new InvalidOperationException(); 
     } 

     T result = m_Vector[0]; 
     m_Vector[0] = m_Vector[m_Vector.Count - 1]; 
     m_Vector.RemoveAt(m_Vector.Count - 1); 

     SiftDown(0); 

     return result; 
    } 
} 

public class MinHeap<T> : Heap<T> where T: IComparable 
{ 
    protected override int Compare(T a, T b) 
    { 
     return a.CompareTo(b); 
    } 

    public MinHeap() : base() 
    { 
    } 

    public MinHeap(IEnumerable<T> elements) : base(elements) 
    { 
    } 
} 

public class MaxHeap<T> : Heap<T> where T : IComparable 
{ 
    protected override int Compare(T a, T b) 
    { 
     return b.CompareTo(a); 
    } 

    public MaxHeap() : base() 
    { 
    } 

    public MaxHeap(IEnumerable<T> elements) : base(elements) 
    { 
    } 
}