题目:

题解:
typedef struct Heap
{
    int* array;   //存放堆的数组
    int  capacity;//数组的容量
    int  len;     //已存数组的大小
}Heap;
                                                        /*大小根堆切换开关*/
int  HeapLen(Heap* hp);                                 //heap获取当前的堆大小
void HeapSwap(int* pLeft, int* pRight);                 //heap交换父子结点的数值
bool HeapEmpty(Heap* hp);                               //heap判空
bool HeapFull(Heap* hp);                                //heap判满
int  HeapGetTop(Heap* hp);                              //heap获取堆顶
void HeapInsert(Heap* hp, int  dat,bool isMax);         //heap向堆的尾部插入1个元素
void HeapDelete(Heap* hp,bool isMax);                    //heap删除堆顶
void HeapAdjustDown(Heap* hp, int parent,bool isMax);   //heap向下调整
void HeapAdjustUp(Heap* hp, int child,bool isMax);      //heap向上调整
Heap* CreateHeap(int size);                             //heap创建
void heapFree(Heap* hp);                                //heap释放空间
int HeapLen(Heap* hp)
{
    return hp->len;
}
bool HeapEmpty(Heap* hp)          //判空
{
    if (HeapLen(hp) == 1)
    {
        return true;
    }
    return false;
}
bool HeapFull(Heap* hp)          //判满
{
    if (hp->capacity == hp->len)
    {
        return true;
    }
    return false;
}
void HeapSwap(int* pLeft, int* pRight)//交换数值
{
    //交换堆中的父子结点
    int  temp;
    temp    = *pLeft;
    *pLeft  = *pRight;
    *pRight = temp;
}
int HeapGetTop(Heap* hp)
{
    return hp->array[1];
}
Heap* CreateHeap(int size)
{
    Heap* heap = (Heap*)malloc(sizeof(Heap));
    int   heapLen = size + 1;//长度比size的长度大1才行
    //给堆申请空间,初始化
    heap->array = (int*)malloc(sizeof(int) * heapLen);
    heap->capacity  = heapLen;     //容量
    heap->len       = 1;           //当前大小
    return heap;
}
void HeapAdjustDown(Heap* hp, int parent ,bool isMax)//向下调整
{
    //标记左右孩子中最小孩子
    int child = 2 * parent;            //左孩子为2*parent  右孩子为 2*parent +1
    int len  = hp->len;
    while (child < len)
    {
        if(isMax)
        {
            //大根堆 选最大的
            //有右子树时 ,找左右孩子中最大的孩子 
            if ((child + 1 < len) && hp->array[child] < hp->array[child + 1])
                child = child + 1;
            //最大孩子大于双亲时 ,孩子与双亲数值交换,否则说明已经调好,不用继续
            if (hp->array[child] > hp->array[parent])
            {
                HeapSwap(&hp->array[child], &hp->array[parent]);
                parent = child;
                child = parent << 1;
            }
            else
                return;
        }
        else
        {
            //小根堆  选最小的
            //有右子树时 ,找左右孩子中最小的孩子 
            if ((child + 1 < len) && hp->array[child] > hp->array[child + 1])
                child = child + 1;
            //最小孩子小于双亲时 ,孩子与双亲数值交换,否则说明已经调好,不用继续
            if (hp->array[child] < hp->array[parent])
            {
                HeapSwap(&hp->array[child], &hp->array[parent]);
                parent = child;
                child = parent << 1;
            }
            else
                return;
        }
    }
}
void HeapAdjustUp(Heap* hp, int child,bool isMax)//向上调整
{
    //得到父母结点的位置
    int parent = child / 2;
    while (child > 1)
    {
        if(isMax)
        {
            //大根堆选择大的
            //循环迭代从child当前位置一直迭代到0位置即对顶
            if (hp->array[child] > hp->array[parent])
            {
                HeapSwap(&hp->array[child], &hp->array[parent]);
                child = parent;
                parent = child/2;
            }
            else
                return;
        }
        else
        {
            //小根堆选择小的
            //循环迭代从child当前位置一直迭代到0位置即对顶
            if (hp->array[child] < hp->array[parent])
            {
                HeapSwap(&hp->array[child], &hp->array[parent]);
                child = parent;
                parent = child/2;
            }
            else
                return;
        }
    }
}
void HeapDelete(Heap* hp,bool isMax)//删除堆顶
{
    if (HeapEmpty(hp))
        return;
    //用最后一个元素覆盖堆顶,相当于删除堆顶
    hp->array[1] = hp->array[hp->len - 1];
    hp->len--;//删除最后一个元素 heap长度变短
    HeapAdjustDown(hp, 1,isMax);//对第一个元素进行调整
}
void HeapInsert(Heap* hp, int  dat,bool isMax)
{
    if (HeapFull(hp))
    {
        //扩容
        hp->capacity <<= 1; 
        hp->array = (int *) realloc(hp->array, hp->capacity * sizeof(int));
    }
    int child = 0;
    int parent = 0;
    //插入到最后一个元素的下一个位置
    hp->array[hp->len++] = dat;
    //调整刚插入元素,
    //因为插入的是堆的尾部,需要堆向上调整
    HeapAdjustUp(hp, hp->len - 1,isMax);
}
void heapFree(Heap* hp)
{
    free(hp->array);
    free(hp);
}
typedef struct 
{
    //左边是 最大堆   右边是小根堆
    //0 1 3              5 7 9 
    Heap* maxLHeap;
    Heap* minRHeap; 
} MedianFinder;
MedianFinder* medianFinderCreate() 
{
    MedianFinder* newMedian = (MedianFinder* )malloc(sizeof(MedianFinder));
    newMedian->maxLHeap = CreateHeap(128);
    newMedian->minRHeap = CreateHeap(128);
    return newMedian;
}
void medianFinderAddNum(MedianFinder* obj, int num)
{
    //检查
    int leftHeapLen = obj->maxLHeap->len;
    int rightHeapLen = obj->minRHeap->len;
    if (leftHeapLen <= rightHeapLen)
    {
        //插入左边的最小堆
        //检查当前值 是否大于 右边的最小堆的堆顶值
        if (!HeapEmpty(obj->minRHeap))
        {
            if (num > obj->minRHeap->array[1])
            {
                //保存当前右边最小堆堆顶值 需要准备移动到 左边 最大堆中
                int  moveValue = obj->minRHeap->array[1];
                //将当前值放到 右边的最小堆 的堆顶
                obj->minRHeap->array[1] = num;
                HeapAdjustDown(obj->minRHeap, 1, false);
                //插入到左边最大堆中
                HeapInsert(obj->maxLHeap, moveValue, true);
                //直接结束了
                return;
            }
        }
        //这里检查 num是小于右边的 最小堆 的堆顶值的
        HeapInsert(obj->maxLHeap, num, true);
    }
    else
    {
        //插入右边的最大堆
        //检查当前值 是否小于 左边的最大堆的堆顶值
        if (!HeapEmpty(obj->maxLHeap))
        {
            if (num < obj->maxLHeap->array[1])
            {
                //保存当前左边最大堆堆顶值 需要准备移动到 右边 最小堆中
                int  moveValue = obj->maxLHeap->array[1];
                //将当前值放到 左边的最da堆 的堆顶
                obj->maxLHeap->array[1] = num;
                HeapAdjustDown(obj->maxLHeap, 1, true);
                //插入到右边最小堆中
                HeapInsert(obj->minRHeap, moveValue, false);
                //直接结束了
                return;
            }
        }
        //这里检查 num是大于左边的 最大堆 的堆顶值的
        HeapInsert(obj->minRHeap, num, false);
    }
}
double medianFinderFindMedian(MedianFinder* obj)
{
    if (obj->maxLHeap->len == obj->minRHeap->len)
    {
        return (double)(obj->minRHeap->array[1] + obj->maxLHeap->array[1]) / 2;
    }
    return (double)obj->maxLHeap->array[1];
}
void medianFinderFree(MedianFinder* obj) 
{
    heapFree(obj->maxLHeap);
    heapFree(obj->minRHeap);
    free(obj);
}
/**
 * Your MedianFinder struct will be instantiated and called as such:
 * MedianFinder* obj = medianFinderCreate();
 * medianFinderAddNum(obj, num);
 
 * double param_2 = medianFinderFindMedian(obj);
 
 * medianFinderFree(obj);
*/















![[OJ]平均串问题,存在超时问题未解决](https://i-blog.csdnimg.cn/blog_migrate/7dc7555f7defc05f3ac8c1decb45b743.png)


