public double  CalculateMedian(MaxHeap <int> maxheap, MinHeap <int> minheap)
 {
     //check for empty..if maxheap is empty then minheap will also be empty
     if (maxheap.Size() == 0)
     {
         return(0);
     }
     if (maxheap.Size() == minheap.Size())
     {
         //mean there are even number of item..median = (sum of middle two items)/2
         return(Convert.ToDouble((maxheap.Peek() + minheap.Peek()) / 2));
     }
     else
     {
         return(maxheap.Peek());
     }
 }
        //Logic:
        //Create maxheap to store max value of the window
        //note: maxheap size doesn't matter
        //Insert first 3 items (window size)
        //loop the other item
        //the heap item has value and index
        //for each item added we insert into the output
        // Generally we should delete the items that are not in the window  eg 3,2,4,5, 6 consider (3,2,4) and then (2,4,5) and then (5,6 etc)
        //but here since we know the heap max we delete the item only if the max heap index is outside the window
        //If the last max heap is outside the current window we remove the peek and then check untill the maxheap index is within the current window
        //Note: here the heap size doesn't matter we may have heap of size 10 for windows of 3 eg input  0,1,2,3,4,5,6,7,8,9,10

        public int[] MaxofSlidingWindowUsingHeap(int[] input, int w)
        {
            int[]          output      = new int[input.Length];
            int            outputindex = 0;
            MaxHeap <Pair> maxheap     = new MaxHeap <Pair>(new KarthicMaxHeapPairComparer());

            //0,1,2
            for (int i = 0; i < w; i++)
            {
                maxheap.Insert(new Pair(input[i], i));
            }
            //we already insert 0 to w-1
            for (int j = w; j < input.Length; j++)
            {
                //previous window peek
                Pair max = maxheap.Peek();
                output[outputindex] = max.Value;
                outputindex++;
                //j - w make sure that only the elements that are lesser than this window should be popped up if it has the peek value
                //update: check whether the max.Index is inside the current window
                //If it is outside the current window then pop and get the next max
                //while (max.Index + w <= j ) this condition is also same
                while (max.Index <= j - w)
                {
                    maxheap.PopRoot();
                    max = maxheap.Peek();
                }

                maxheap.Insert(new Pair(input[j], j));
            }


            Pair max1 = maxheap.Peek();

            output[outputindex] = max1.Value;
            outputindex++;


            Array.Resize <int>(ref output, outputindex);

            return(output);
        }
        private void button3_Click(object sender, EventArgs e)
        {
            int[] input = AlgorithmHelper.ConvertCommaSeparetedStringToInt(this.textBox1.Text);


            //Assumption:
            //1) Store the values lesser than median in max heap and keep the root with the max value
            //2) Store the values greater than the median in min heap
            //3) Maxheap >= Minheap

            //* Use a max heap and a min heap to maintain the stream, where
            //* maxheap.size() == minheap.size() or
            //* maxheap.size() - 1 == minheap.size()
            //* always holds.

// Similar to balancing BST in Method 2 above, we can use a max heap on left side to represent elements that are less than effective median, and a min heap on right side to represent elements that are greater than effective median.

//After processing an incoming element, the number of elements in heaps differ utmost by 1 element. When both heaps contain same number of elements, we pick average of heaps root data as effective median. When the heaps are not balanced, we select effective median from the root of heap containing more elements.

            MinHeap <int> minheap = new MinHeap <int>(new KarthicMinHeapComparer2());
            MaxHeap <int> maxheap = new MaxHeap <int>(new KarthicMaxHeapComparer());



            foreach (int i in input)
            {
                InsertRandomElement(i, maxheap, minheap);
            }


            //Median Calcualtion
            //If there are odd total numbers, maxheap will be greater
            //if there are even total number then minheap == maxheap

            this.textBox2.Text = CalculateMedian(maxheap, minheap).ToString();
        }
        public int FindthekthLargestElementInMatrix(int[,] matrix, int k)
        {
            MaxHeap <MatrixElement> myheap = new MaxHeap <MatrixElement>(new MaxMatrixElementComparer());

            //add last row to max heap//all col in first row
            int lastrow = matrix.GetLength(1) - 1;

            for (int col = 0; col < matrix.GetLength(1); col++)
            {
                myheap.Insert(new MatrixElement(matrix[lastrow, col], lastrow, col));
            }

            // to find kth smallest..iterate k times
            for (int i = 1; i < k; i++)
            {
                //get the min
                MatrixElement maxelement = myheap.Peek();
                //Find the next element in the next row of the same colmumn
                //check the next row is not ourside bounds
                if (maxelement.Row - 1 >= 0)
                {
                    MatrixElement nextelement = new MatrixElement(matrix[maxelement.Row - 1, maxelement.Col], maxelement.Row - 1, maxelement.Col);

                    //we can update the heap root element and then call minheapify of the root
                    //my heap fon't prov that so
                    myheap.PopRoot();
                    myheap.Insert(nextelement); //this will make sure to have the smallest
                }
                else
                {
                    myheap.PopRoot();
                }
            }

            return(myheap.Peek().Data);
        }