Advertisement
Guest User

HeapShit

a guest
Sep 17th, 2014
304
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 8.59 KB | None | 0 0
  1.     interface SomeData
  2.     {
  3.         void Push(long element);
  4.         long Pop();
  5.         long GetMax();
  6.         void RemoveMax();
  7.     }
  8.  
  9.     public class StupidDatum
  10.     {
  11.         public long value;
  12.         public int heapIndex = -1;
  13.         public LinkedListNode<StupidDatum> listNode;
  14.  
  15.         public StupidDatum(long value)
  16.         {
  17.             this.value = value;
  18.             listNode = new LinkedListNode<StupidDatum>(this);
  19.         }
  20.     }
  21.     public static class HeapTests
  22.     {
  23.         [Test]
  24.         public static void IsHeapish()
  25.         {
  26.             List<long> data = new List<long>();
  27.             int curValue = 234246233;
  28.  
  29.             for (int ix = 0; ix < 100; ix++)
  30.             {
  31.                 curValue = curValue * 1345378247;
  32.                 data.Add(curValue);
  33.             }
  34.  
  35.             StupidHeap heap = new StupidHeap(data.Count);
  36.             data.Select(x => new StupidDatum(x)).ToList().ForEach(heap.Add);
  37.  
  38.             data.Sort();
  39.             data.Reverse();
  40.  
  41.             while(data.Count > 0)
  42.             {
  43.                 Assert.AreEqual(data.First(), heap.GetMax());
  44.                 if(0 != heap.MaxObj().heapIndex)
  45.                 {
  46.                     Assert.AreEqual(0, heap.MaxObj().heapIndex);
  47.                 }
  48.                 data.RemoveAt(0);
  49.                 heap.RemoveMax();
  50.             }
  51.         }
  52.     }
  53.     public class StupidHeap
  54.     {
  55.         int endIndex = 0;
  56.         StupidDatum[] buffer;
  57.  
  58.         static int[] levelStarts;
  59.         static StupidHeap()
  60.         {
  61.             List<int> levelStarts = new List<int>();
  62.  
  63.             long maxSize = long.MaxValue;
  64.  
  65.             int count = 1;
  66.             int pos = 0;
  67.             while (maxSize > 0)
  68.             {
  69.                 levelStarts.Add(pos);
  70.                 maxSize -= count;
  71.                 pos += count;
  72.                 count *= 2;
  73.             }
  74.  
  75.             StupidHeap.levelStarts = levelStarts.ToArray();
  76.         }
  77.  
  78.         public StupidHeap() { }
  79.         public StupidHeap(int maxSize)
  80.         {
  81.             buffer = new StupidDatum[maxSize];
  82.         }
  83.  
  84.         public StupidDatum MaxObj()
  85.         {
  86.             return buffer[0];
  87.         }
  88.  
  89.         public long GetMax()
  90.         {
  91.             if (endIndex == 0) return long.MinValue;
  92.             return buffer[0].value;
  93.         }
  94.         public void Add(StupidDatum value)
  95.         {
  96.             value.heapIndex = endIndex;
  97.             buffer[endIndex++] = value;
  98.  
  99.             BubbleUp(endIndex - 1);
  100.         }
  101.  
  102.         [Test]
  103.         [TestCase(0, ExpectedResult = 0)]
  104.         [TestCase(1, ExpectedResult = 1)]
  105.         [TestCase(2, ExpectedResult = 1)]
  106.         [TestCase(3, ExpectedResult = 2)]
  107.         [TestCase(14, ExpectedResult = 3)]
  108.         [TestCase(15, ExpectedResult = 4)]
  109.         public static int Level(int index)
  110.         {
  111.             int level = 0;
  112.             while(index >= levelStarts[level])
  113.             {
  114.                 level++;
  115.             }
  116.             return level - 1;
  117.         }
  118.         [Test]
  119.         [TestCase(0, ExpectedResult = 0)]
  120.         [TestCase(2, ExpectedResult = 0)]
  121.         [TestCase(5, ExpectedResult = 2)]
  122.         [TestCase(6, ExpectedResult = 2)]
  123.         [TestCase(7, ExpectedResult = 3)]
  124.         [TestCase(11, ExpectedResult = 5)]
  125.         [TestCase(14, ExpectedResult = 6)]
  126.         public static int Parent(int index)
  127.         {
  128.             if (index == 0) return 0;
  129.  
  130.             int level = Level(index);
  131.  
  132.             int start = levelStarts[level];
  133.             int prevStart = levelStarts[level - 1];
  134.  
  135.             return prevStart + (index - start) / 2;
  136.         }
  137.         [Test]
  138.         [TestCase(0, ExpectedResult = 1)]
  139.         [TestCase(1, ExpectedResult = 3)]
  140.         [TestCase(2, ExpectedResult = 5)]
  141.         [TestCase(3, ExpectedResult = 7)]
  142.         [TestCase(4, ExpectedResult = 9)]
  143.         [TestCase(5, ExpectedResult = 11)]
  144.         [TestCase(6, ExpectedResult = 13)]
  145.         public static int LeftChild(int index)
  146.         {
  147.             int level = Level(index);
  148.  
  149.             int start = levelStarts[level];
  150.             int nextStart = levelStarts[level + 1];
  151.  
  152.             return nextStart + (index - start) * 2;
  153.         }
  154.         public static int RightChild(int index)
  155.         {
  156.             return LeftChild(index) + 1;
  157.         }
  158.         public void RemoveMax()
  159.         {
  160.             Remove(0);
  161.         }
  162.         public void Remove(int index)
  163.         {
  164.             buffer[index] = buffer[--endIndex];
  165.             buffer[index].heapIndex = index;
  166.  
  167.             index = BubbleUp(index);
  168.             BubbleDown(index);
  169.         }
  170.         private void BubbleDown(int index)
  171.         {
  172.             var ourObj = buffer[index];
  173.             long ourVal = buffer[index].value;
  174.  
  175.             while (true)
  176.             {
  177.                 long leftValue = ourVal;
  178.                 long rightVal = ourVal;
  179.  
  180.                 int leftIndex = LeftChild(index);
  181.                 if (leftIndex < endIndex)
  182.                 {
  183.                     leftValue = buffer[leftIndex].value;
  184.                 }
  185.                 int rightIndex = RightChild(index);
  186.                 if (rightIndex < endIndex)
  187.                 {
  188.                     rightVal = buffer[rightIndex].value;
  189.                 }
  190.  
  191.                 if (ourVal >= leftValue && ourVal >= rightVal) return;
  192.  
  193.                 bool leftSide = ourVal < leftValue;
  194.                 if (ourVal < rightVal && rightVal > leftValue)
  195.                 {
  196.                     leftSide = false;
  197.                 }
  198.  
  199.                 if (leftSide)
  200.                 {
  201.                     buffer[index] = buffer[leftIndex];
  202.                     buffer[index].heapIndex = index;
  203.                     buffer[leftIndex] = ourObj;
  204.                     index = leftIndex;
  205.                 }
  206.                 else
  207.                 {
  208.                     buffer[index] = buffer[rightIndex];
  209.                     buffer[index].heapIndex = index;
  210.                     buffer[rightIndex] = ourObj;
  211.                     index = rightIndex;
  212.                 }
  213.  
  214.                 ourObj.heapIndex = index;
  215.             }
  216.         }
  217.         private int BubbleUp(int index)
  218.         {
  219.             var val = buffer[index];
  220.             long value = val.value;
  221.  
  222.             while (index != 0)
  223.             {
  224.                 int parentIndex = Parent(index);
  225.                 StupidDatum parVal = buffer[parentIndex];
  226.                 if (value <= parVal.value) break;
  227.                 //Swap with parent and continue
  228.                 buffer[index] = parVal; parVal.heapIndex = index;
  229.                 buffer[parentIndex] = val; val.heapIndex = parentIndex;
  230.                 index = parentIndex;
  231.             }
  232.             return index;
  233.         }
  234.     }
  235.  
  236.     public static class LinkedImplTests
  237.     {
  238.         [Test]
  239.         public static void FuckThis()
  240.         {
  241.             LinkedImpl test = new LinkedImpl(100);
  242.             test.Push(5);
  243.             test.Push(6);
  244.             test.Push(7);
  245.             test.Push(4);
  246.             test.Push(2);
  247.  
  248.             Assert.AreEqual(7, test.GetMax());
  249.             test.RemoveMax();
  250.             Assert.AreEqual(6, test.GetMax());
  251.  
  252.             test.Push(10);
  253.             test.Push(1);
  254.             Assert.AreEqual(10, test.GetMax());
  255.             test.Pop();
  256.             Assert.AreEqual(10, test.GetMax());
  257.             test.Pop();
  258.             Assert.AreEqual(6, test.GetMax());
  259.  
  260.             test.Pop();
  261.             test.Pop();
  262.             test.Pop();
  263.             test.Pop();
  264.             Assert.AreEqual(5, test.GetMax());
  265.         }
  266.     }
  267.  
  268.     public class LinkedImpl : SomeData
  269.     {
  270.         private LinkedList<StupidDatum> linkedList = new LinkedList<StupidDatum>();
  271.         private StupidHeap heap;
  272.  
  273.         public LinkedImpl(int maxElems)
  274.         {
  275.             heap = new StupidHeap(maxElems);
  276.         }
  277.  
  278.         public void Push(long element)
  279.         {
  280.             StupidDatum elem = new StupidDatum(element);
  281.  
  282.             linkedList.AddLast(elem.listNode);
  283.             heap.Add(elem);
  284.         }
  285.  
  286.         public long Pop()
  287.         {
  288.             var val = linkedList.Last;
  289.  
  290.             heap.Remove(val.Value.heapIndex);
  291.             linkedList.Remove(val);
  292.  
  293.             return val.Value.value;
  294.         }
  295.  
  296.         public long GetMax()
  297.         {
  298.             var val = heap.MaxObj();
  299.             if (val == null) return long.MinValue;
  300.             return val.value;
  301.         }
  302.  
  303.         public void RemoveMax()
  304.         {
  305.             var val = heap.MaxObj();
  306.             if (val == null) return;
  307.  
  308.             heap.Remove(val.heapIndex);
  309.             linkedList.Remove(val.listNode);
  310.         }
  311.     }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement