题解 | #数据流中的中位数#
数据流中的中位数
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;
}
查看15道真题和解析