About

This is an implementation of Binary Heap Tree using generics and arrays as backend storage in C#.

Code

using System;
 
namespace Heap
{
    internal class Program
    {
        private static void Main(string[] args)
        {
            var heap = new MaxHeap<int>(new[] {9, 10, 2, 7, 8, 9, 20, 21});
 
            heap.PrintTree();
            Console.ReadKey();
        }
 
        ///////////////////////////////////////////////////////////////////////////
        //  Copyright (C) Wizardry and Steamworks 2016 - License: GNU GPLv3      //
        //  Please see: http://www.gnu.org/licenses/gpl.html for legal details,  //
        //  rights of fair usage, the disclaimer and warranty conditions.        //
        ///////////////////////////////////////////////////////////////////////////
        /// <summary>
        ///     A max-heap implementation.
        /// </summary>
        private class MaxHeap<T> where T : IComparable
        {
            private readonly int size;
            private readonly T[] store;
            private int count;
 
            /// <summary>
            ///     Initializes a store of a given size.
            /// </summary>
            /// <param name="size"></param>
            public MaxHeap(int size)
            {
                store = new T[size];
                this.size = size;
            }
 
            /// <summary>
            ///     Initializes a store from an array of values.
            /// </summary>
            /// <param name="values">the values to add to the store</param>
            /// <remarks>Uses Floyd's algorithm to heapify.</remarks>
            public MaxHeap(T[] values)
            {
                store = values;
                size = values.Length;
                count = values.Length;
                for (var i = values.Length - 1; i > -1; --i)
                {
                    TrickleDown(i);
                }
            }
 
            /// <summary>
            ///     Adds an item to the store.
            /// </summary>
            /// <param name="item">the item to add</param>
            public void Add(T item)
            {
                if (count + 1 > size)
                    throw new ArgumentOutOfRangeException();
 
                store[count] = item;
                TrickleUp(count);
                ++count;
            }
 
            /// <summary>
            ///     Extracts the root node.
            /// </summary>
            /// <returns>the root node</returns>
            public T Extract()
            {
                if (count == 0)
                    throw new ArgumentOutOfRangeException();
 
                var tmp = store[0];
                store[0] = store[count - 1];
                --count;
                TrickleDown(0);
                return tmp;
            }
 
            /// <summary>
            ///     Internal function to swap to items on the store.
            /// </summary>
            /// <param name="u">first index</param>
            /// <param name="v">second index</param>
            private void HeapSwap(int u, int v)
            {
                var t = store[u];
                store[u] = store[v];
                store[v] = t;
            }
 
            /// <summary>
            ///     Determines if the store is empty.
            /// </summary>
            /// <returns>true in case the store is empty</returns>
            public bool IsEmpty()
            {
                return count == 0;
            }
 
            /// <summary>
            ///     Trickles up a node at a given index.
            /// </summary>
            /// <param name="i">the index of the node</param>
            private void TrickleUp(int i)
            {
                if (i < 0) return;
 
                var p = (i - 1)/2;
 
                if (store[i].CompareTo(store[p]) <= 0) return;
 
                HeapSwap(p, i);
                TrickleUp(p);
            }
 
            /// <summary>
            ///     Trickles down a node at a given index.
            /// </summary>
            /// <param name="i">the index of the node</param>
            private void TrickleDown(int i)
            {
                var l = 2*i + 1;
                var r = 2*i + 2;
                var c = i;
 
                if (l < count && store[l].CompareTo(store[c]) > 0)
                    c = l;
                if (r < count && store[r].CompareTo(store[c]) > 0)
                    c = r;
 
                if (c == i) return;
 
                HeapSwap(c, i);
                TrickleDown(c);
            }
 
            /// <summary>
            ///     Calculates the depth of the store.
            /// </summary>
            /// <param name="i">the index from where to start counting</param>
            /// <returns>the depth of the store</returns>
            public int Depth(int i)
            {
                if (i >= count)
                    return 0;
 
                var l = Depth(2*i + 1);
                var r = Depth(2*i + 2);
 
                return l > r ? l + 1 : r + 1;
            }
 
            /// <summary>
            ///     Prints out the tree starting from an index and a level.
            /// </summary>
            /// <param name="i">the starting node</param>
            /// <param name="level">the level at which to start</param>
            private void PrintTree(int i, int level)
            {
                if (i >= count)
                    return;
 
                var l = 2*i + 1;
                var r = 2*i + 2;
 
                if (l < count)
                    PrintTree(l, level + 1);
 
                for (var t = level; t > 0; --t)
                {
                    Console.Write("\t");
                }
 
                Console.WriteLine(store[i]);
 
                if (r < count)
                    PrintTree(r, level + 1);
            }
 
            /// <summary>
            ///     Print out the entire tree.
            /// </summary>
            public void PrintTree()
            {
                PrintTree(0, 0);
            }
        }
    }
}

csharp/binary_heap_tree.txt ยท Last modified: 2022/04/19 08:28 by 127.0.0.1

Access website using Tor Access website using i2p Wizardry and Steamworks PGP Key


For the contact, copyright, license, warranty and privacy terms for the usage of this website please see the contact, license, privacy, copyright.