c#中的Fibonacci,Binary或Binomial堆?

时间:2009-01-09 16:50:23

标签: c# .net algorithm data-structures

是否有任何堆数据结构实现,斐波那契,二进制或二项式?

参考:这些是用于实现优先级队列的数据结构,而不是用于分配动态内存的数据结构。见http://en.wikipedia.org/wiki/Heap_(data_structure)

谢谢, 戴夫

7 个答案:

答案 0 :(得分:6)

堆栈和许多其他数据结构的免费C#实现:

答案 1 :(得分:5)

QuickGraph在C#中实现斐波纳契堆和队列,以及其他很多东西。它是免费和开源的。

答案 2 :(得分:3)

单独的压力测试实现在PSR-4 autoloading存储库(我拥有它)下的Github中。 DecrementKey操作性能是后来两个重要的。

  • Bin Min / Max Heap
  • 二项式最小值/最大值
  • Fibornacci Min / Max Heap

存储库还有两个堆实现,D-Ary Heap&配对堆。

答案 3 :(得分:2)

我不知道任何本机框架实现。

我发现了两个二进制堆实现(link 1link 2)和f#(link)中二项堆的一个实现。

答案 4 :(得分:2)

我相信带有自定义SortedSet<KeyValuePair<K,V>>的{​​{1}}可以胜任。

Comparer如下所示:

Comparer

使用此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; } } Comparer将按键进行排序,它将允许重复键。

您可以定时SortedSetMin RemoveMinO(logn) Add条目{}} O(logn) Update

这是一个完整的(或几乎)实现:

O(logn)

答案 5 :(得分:0)

简单的最小堆实现。

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();
*/

答案 6 :(得分:0)

MinHeap和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)
    {
    }
}