CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 5 of 5
  1. #1
    Join Date
    Dec 2010
    Posts
    907

    What is the best matching data structure for C# binary heaps in C++ with boost?

    I wonder are there boost available structures that act pretty much the same as binary heaps of C# in VC++?
    like this code snippet in C#

    Code:
     BinaryHeap<Node> OpenList = new BinaryHeap<Node>();
     BinaryHeap<Node> ClosedList = new BinaryHeap<Node>();
    Code:
    namespace LibAStar
    {
        /// <summary>
        /// A binary heap, useful for sorting data and priority queues.
        /// </summary>
        /// <typeparam name="T"><![CDATA[IComparable<T> type of item in the heap]]>.</typeparam>
        public class BinaryHeap<T> : ICollection<T> where T : IComparable<T>
        {
            // Constants
            private const int DEFAULT_SIZE = 100;
            // Fields
            private T[] _data = new T[DEFAULT_SIZE];
            private int _count = 0;
            private int _capacity = DEFAULT_SIZE;
            private bool _sorted;
    
            // Properties
            /// <summary>
            /// Gets the number of values in the heap. 
            /// </summary>
            public int Count
            {
                get { return _count; }
            }
            /// <summary>
            /// Gets or sets the capacity of the heap.
            /// </summary>
            public int Capacity
            {
                get { return _capacity; }
                set
                {
                    int previousCapacity = _capacity;
                    _capacity = Math.Max(value, _count);
                    if (_capacity != previousCapacity)
                    {
                        T[] temp = new T[_capacity];
                        Array.Copy(_data, temp, _count);
                        _data = temp;
                    }
                }
            }
            // Methods
            /// <summary>
            /// Creates a new binary heap.
            /// </summary>
            public BinaryHeap()
            {
            }
            private BinaryHeap(T[] data, int count)
            {
                Capacity = count;
                _count = count;
                Array.Copy(data, _data, count);
            }
            /// <summary>
            /// Gets the first value in the heap without removing it.
            /// </summary>
            /// <returns>The lowest value of type TValue.</returns>
            public T Peek()
            {
                return _data[0];
            }
    
            /// <summary>
            /// Removes all items from the heap.
            /// </summary>
            public void Clear()
            {
                this._count = 0;
                _data = new T[_capacity];
            }
            /// <summary>
            /// Adds a key and value to the heap.
            /// </summary>
            /// <param name="item">The item to add to the heap.</param>
            public void Add(T item)
            {
                if (_count == _capacity)
                {
                    Capacity *= 2;
                }
                _data[_count] = item;
                UpHeap();
                _count++;
            }
    
            /// <summary>
            /// Removes and returns the first item in the heap.
            /// </summary>
            /// <returns>The next value in the heap.</returns>
            public T Remove()
            {
                if (this._count == 0)
                {
                    throw new InvalidOperationException("Cannot remove item, heap is empty.");
                }
                T v = _data[0];
                _count--;
                _data[0] = _data[_count];
                _data[_count] = default(T); //Clears the Last Node
                DownHeap();
                return v;
            }
            private void UpHeap()
            //helper function that performs up-heap bubbling
            {
                _sorted = false;
                int p = _count;
                T item = _data[p];
                int par = Parent(p);
                while (par > -1 && item.CompareTo(_data[par]) < 0)
                {
                    _data[p] = _data[par]; //Swap nodes
                    p = par;
                    par = Parent(p);
                }
                _data[p] = item;
            }
            private void DownHeap()
            //helper function that performs down-heap bubbling
            {
                _sorted = false;
                int n;
                int p = 0;
                T item = _data[p];
                while (true)
                {
                    int ch1 = Child1(p);
                    if (ch1 >= _count) break;
                    int ch2 = Child2(p);
                    if (ch2 >= _count)
                    {
                        n = ch1;
                    }
                    else
                    {
                        n = _data[ch1].CompareTo(_data[ch2]) < 0 ? ch1 : ch2;
                    }
                    if (item.CompareTo(_data[n]) > 0)
                    {
                        _data[p] = _data[n]; //Swap nodes
                        p = n;
                    }
                    else
                    {
                        break;
                    }
                }
                _data[p] = item;
            }
            private void EnsureSort()
            {
                if (_sorted) return;
                Array.Sort(_data, 0, _count);
                _sorted = true;
            }
            private static int Parent(int index)
            //helper function that calculates the parent of a node
            {
                return (index - 1) >> 1;
            }
            private static int Child1(int index)
            //helper function that calculates the first child of a node
            {
                return (index << 1) + 1;
            }
            private static int Child2(int index)
            //helper function that calculates the second child of a node
            {
                return (index << 1) + 2;
            }
    
            /// <summary>
            /// Creates a new instance of an identical binary heap.
            /// </summary>
            /// <returns>A BinaryHeap.</returns>
            public BinaryHeap<T> Copy()
            {
                return new BinaryHeap<T>(_data, _count);
            }
    
            /// <summary>
            /// Gets an enumerator for the binary heap.
            /// </summary>
            /// <returns>An IEnumerator of type T.</returns>
            public IEnumerator<T> GetEnumerator()
            {
                EnsureSort();
                for (int i = 0; i < _count; i++)
                {
                    yield return _data[i];
                }
            }
            System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
            {
                return GetEnumerator();
            }
    
            /// <summary>
            /// Checks to see if the binary heap contains the specified item.
            /// </summary>
            /// <param name="item">The item to search the binary heap for.</param>
            /// <returns>A boolean, true if binary heap contains item.</returns>
            public bool Contains(T item)
            {
                EnsureSort();
                return Array.BinarySearch<T>(_data, 0, _count, item) >= 0;
            }
            /// <summary>
            /// Copies the binary heap to an array at the specified index.
            /// </summary>
            /// <param name="array">One dimensional array that is the destination of the copied elements.</param>
            /// <param name="arrayIndex">The zero-based index at which copying begins.</param>
            public void CopyTo(T[] array, int arrayIndex)
            {
                EnsureSort();
                Array.Copy(_data, array, _count);
            }
            /// <summary>
            /// Gets whether or not the binary heap is readonly.
            /// </summary>
            public bool IsReadOnly
            {
                get { return false; }
            }
            /// <summary>
            /// Removes an item from the binary heap. This utilizes the type T's Comparer and will not remove duplicates.
            /// </summary>
            /// <param name="item">The item to be removed.</param>
            /// <returns>Boolean true if the item was removed.</returns>
            public bool Remove(T item)
            {
                EnsureSort();
                int i = Array.BinarySearch<T>(_data, 0, _count, item);
                if (i < 0) return false;
                Array.Copy(_data, i + 1, _data, i, _count - i);
                _data[_count] = default(T);
                _count--;
                return true;
            }
    
        }
    }
    Thanks
    Jack
    Last edited by lucky6969b; May 5th, 2015 at 07:28 AM.

  2. #2
    Join Date
    Jul 2013
    Posts
    576

    Re: What is the best matching data structure for C# binary heaps in C++ with boost?

    Quote Originally Posted by lucky6969b View Post
    I wonder are there boost available structures that act pretty much the same as binary heaps of C# in VC++?
    As an abstract data type a heap is called a priority queue so that's what you should be looking for.

    The C++ standard library has one called std:: priority_queue and I'm quite certain there is one also in Boost.

    In principle any sorted data structure can be used as a heap (priority queue). The min/max elements are readily avalilable at the beginning/end. This means for example std::set can be used as heap. And since you can access the min/max (first/last) elements in constant time it even has the complexity you would expect from a dedicated heap implementation.

    What you don't get is access to the internal structure of a binary tree heap implementation, that is the elements ordered according to the so called "heap property". You probably won't find that anywhere in standard libraries since it's implementation detail and standard libraries deal in abstractions.
    Last edited by razzle; May 6th, 2015 at 02:35 AM.

  3. #3
    Join Date
    Oct 2008
    Posts
    1,456

    Re: What is the best matching data structure for C# binary heaps in C++ with boost?

    FYI, the c++ standard library also sports a set of heap functions ( make_heap, etc ... ) that allows you managing any mutable random access sequence as a heap, with no space overhead ( and no time overhead of a fully sorted sequence ).

    BTW, priority_queue is nothing but a wrapper around the aforementioned heap functions. That said, priority_queue has the advantage of incapsulating the underlying container in a "pure" heap interface, so that you're (almost) sure that the heap invariants are preserved ... so, it's probably the most straightforward drop in replacement, as razzle said

  4. #4
    Join Date
    Dec 2010
    Posts
    907

    Re: What is the best matching data structure for C# binary heaps in C++ with boost?

    Hi,
    When I setup a priority_queue for this purpose, the only thing lacking is something like

    pq.erase(element);

    I can push it, pop it, top it but never erase a certain element in the middle of the heap...
    Thanks
    Jack

  5. #5
    Join Date
    Oct 2008
    Posts
    1,456

    Re: What is the best matching data structure for C# binary heaps in C++ with boost?

    well, then use a std:: set as razzle suggested, or, if you really need an heap for performance reasons and erasures are rare, you can use a std:: vector with the heap functions I previeously referred to, or you can copy the priority queue to a vector/set, perform any operation on it, and copy it back to the queue once finished ...

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured