题解 | #数据流中的中位数#

数据流中的中位数

https://www.nowcoder.com/practice/9be0172896bd43948f8a32fb954e1be1

typedef struct Heap {
    int* context;
    int size;//当前个数
    int capacity;//最大个数
} Heap;

Heap* heap_max;
Heap* heap_min;

void heap_adjust_up_min(Heap* heap, int child);//上根堆上滤
void heap_adjust_down_min(Heap* heap, int root);//小根堆下滤(用于pop)
void heap_adjust_up_max(Heap* heap, int child);//大根堆上滤
void heap_adjust_down_max(Heap* heap, int root);//大根堆下滤(pop)
void swap(int* a,int*b){
    int temp=*a;
    *a=*b;
    *b=temp;
}

void heap_min_push(Heap* heap, int n) {
    if (heap->size == heap->capacity) {
        heap->context = (int*)realloc(heap->context,
                                      ((heap->capacity + 1) * 2 - 1) * sizeof(int));
        heap->capacity = (heap->capacity + 1) * 2 - 1;
    }

    heap->context[heap->size] = n;
    heap->size++;
    heap_adjust_up_min(heap, heap->size - 1);
}

void heap_max_push(Heap* heap, int n) {
    if (heap->size == heap->capacity) {
        heap->context = (int*)realloc(heap->context,
                                      ((heap->capacity + 1) * 2 - 1) * sizeof(int));
        heap->capacity = (heap->capacity + 1) * 2 - 1;
    }

    heap->context[heap->size] = n;
    heap->size++;
    heap_adjust_up_max(heap, heap->size - 1);
}

void heap_adjust_up_min(Heap* heap, int child) {
    int parent = (child - 1) / 2;//最后加入节点的父亲节点
    int temp;

    while (child > 0) {
        if (heap->context[parent] > heap->context[child]) {
            //父亲节点大,小根堆上滤
            swap(&heap->context[parent] , &heap->context[child]);
            child = parent;
            parent = (child - 1) / 2;
        } else break;
    }
}

void heap_adjust_up_max(Heap* heap, int child) {
    int parent = (child - 1) / 2;
    int temp;

    while (child > 0) {
        if (heap->context[parent] < heap->context[child]) {
            swap(&heap->context[parent] , &heap->context[child]);

            child = parent;
            parent = (child - 1) / 2;
        } else break;
    }
}

void heap_pop_min(Heap* heap) {
    //堆的根和最后一个节点交换
    swap(&heap->context[0],&heap->context[heap->size - 1]);
    --heap->size;//节点数--;
    heap_adjust_down_min(heap, 0);
}

void heap_pop_max(Heap* heap) {
    swap(&heap->context[0],&heap->context[heap->size - 1]);
    --heap->size;
    heap_adjust_down_max(heap, 0);
}

void heap_adjust_down_min(Heap* heap, int root) {
    int parent = root;
    int child = parent * 2 + 1; // 第一个子节点

    while (child < heap->size) {
        //选出最小的child节点数
        if (child + 1 < heap->size && heap->context[child + 1] < heap->context[child])
            ++child;
        //父亲节点大就交换
        if (heap->context[parent] > heap->context[child]) {
            swap(&heap->context[parent],&heap->context[child]);
            parent = child;
            child = parent * 2 + 1;
        } else break;
    }
}

void heap_adjust_down_max(Heap* heap, int root) {
    int parent = root;
    int child = parent * 2 + 1; // 第一个子节点

    while (child < heap->size) {
        if (child + 1 < heap->size && heap->context[child + 1] > heap->context[child])
            ++child;

        if (heap->context[parent] < heap->context[child]) {
            swap(&heap->context[parent],&heap->context[child]);
            parent = child;
            child = parent * 2 + 1;
        } else break;
    }
}

Heap* init_heap(Heap* heap, int first) {
    heap = (Heap*)malloc(sizeof(Heap));
    heap->size = 0;
    heap->capacity = 1;
    heap->context = (int*)malloc(sizeof(int));
    heap->context[0] = first;
    return heap;
}

void Insert(int num) {
    // write code here
    if (heap_max == NULL || heap_min == NULL) {
        heap_min = init_heap(heap_min, -100000);
        heap_max = init_heap(heap_max, 100000);
    }

    heap_min_push(heap_min, num);
    //不让小根堆数超过大根堆
    if (heap_min->size > heap_max->size) {
        heap_max_push(heap_max, heap_min->context[0]);
        heap_pop_min(heap_min);
    } 
    else if (heap_min->size == heap_max->size) {
        //小根堆的数必须>大根堆的数
        if (heap_min->context[0] < heap_max->context[0]) {
            heap_max_push(heap_max, heap_min->context[0]);
            heap_pop_min(heap_min);
            heap_min_push(heap_min, heap_max->context[0]);
            heap_pop_max(heap_max);
        }
    }
}

double GetMedian() {
    // write code here
    double result;
    if (heap_min->size < heap_max->size) result = (double)heap_max->context[0];
    else result = ((double)heap_max->context[0] + (double)heap_min->context[0]) /2.0;
    return result;
}

全部评论

相关推荐

点赞 评论 收藏
分享
shtdbb_:还不错,没有让你做了笔试再挂你
点赞 评论 收藏
分享
10-18 13:01
已编辑
西安理工大学 C++
小米内推大使:建议技能还是放上面吧,hr和技术面试官第一眼想看的应该是技能点和他们岗位是否匹配
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务