This is an implementation of Binary Heap Tree using generics and arrays as backend storage in C#.
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); } } } }