typedef struct {
int *data1;
int index1;
int *data2;
int index2;
} MedianFinder;
/** initialize your data structure here. */
MedianFinder* medianFinderCreate() {
MedianFinder *h;
h = malloc(sizeof(MedianFinder));
h->data1 = malloc(sizeof(int));
h->index1 = 0;
h->data2 = malloc(sizeof(int));
h->index2 = 0;
return h;
}
void InsertBigHeap(MedianFinder *h, int num)
{
int i, j;
h->data1[h->index1] = num;
i = h->index1;
j = (i - 1) / 2;
while (i != 0)
{
if (h->data1[j] > num)
break;
h->data1[i] = h->data1[j];
i = j;
j = (i - 1) / 2;
}
h->data1[i] = num;
h->index1++;
h->data1 = realloc(h->data1, (h->index1 + 1)*sizeof(int));
return;
}
void InsertLittleHeap(MedianFinder *h, int num)
{
int i, j;
h->data2[h->index2] = num;
i = h->index2;
j = (i - 1) / 2;
while (i != 0)
{
if (h->data2[j] < num)
break;
h->data2[i] = h->data2[j];
i = j;
j = (i - 1) / 2;
}
h->data2[i] = num;
h->index2++;
h->data2 = realloc(h->data2, (h->index2 + 1)*sizeof(int));
return;
}
void DeleteBigHeap(MedianFinder *h)
{
int i, j, temp;
i = h->index1 - 1;
h->index1--;
h->data1[0] = h->data1[i];
temp = h->data1[0];
i = 0;
j = 2 * i + 1;
while (j < h->index1)
{
if (j < h->index1 - 1 && h->data1[j] < h->data1[j + 1])
j++;
if (h->data1[j] < temp)
break;
h->data1[i] = h->data1[j];
i = j;
j = 2 * i + 1;
}
h->data1[i] = temp;
return;
}
void DeleteLittleHeap(MedianFinder *h)
{
int i, j, temp;
i = h->index2 - 1;
h->index2--;
h->data2[0] = h->data2[i];
temp = h->data2[0];
i = 0;
j = 2 * i + 1;
while (j < h->index2)
{
if (j<h->index2 - 1 && h->data2[j]>h->data2[j + 1])
j++;
if (h->data2[j] > temp)
break;
h->data2[i] = h->data2[j];
i = j;
j = 2 * i + 1;
}
h->data2[i] = temp;
return;
}
void medianFinderAddNum(MedianFinder* obj, int num) {
double temp1;
double temp2;
if (obj->index1 == 0)
{
obj->data1[obj->index1] = num;
obj->index1++;
obj->data1 = realloc(obj->data1, (obj->index1 + 1)*sizeof(int));
}
else if (obj->index2 == 0)
{
obj->data2[obj->index2] = num;
obj->index2++;
obj->data2 = (int *)realloc(obj->data2, (obj->index2 + 1) * sizeof(int));
}
else if (obj->index1 == obj->index2)
{
if (num > obj->data1[0])
InsertLittleHeap(obj, num);
else
InsertBigHeap(obj, num);
if (obj->data1[0] > obj->data2[0])
{
temp1 = obj->data1[0];
temp2 = obj->data2[0];
DeleteBigHeap(obj);
DeleteLittleHeap(obj);
InsertBigHeap(obj, temp2);
InsertLittleHeap(obj, temp1);
}
}
else if (obj->index1 > obj->index2)
{
if (num > obj->data1[0])
InsertLittleHeap(obj, num);
else
{
InsertBigHeap(obj, num);
InsertLittleHeap(obj, obj->data1[0]);
DeleteBigHeap(obj);
}
}
else if (obj->index1 < obj->index2)
{
if (num < obj->data1[0])
InsertBigHeap(obj, num);
else
{
InsertLittleHeap(obj, num);
InsertBigHeap(obj, obj->data2[0]);
DeleteLittleHeap(obj);
}
}
return;
}
double medianFinderFindMedian(MedianFinder* obj) {
if (obj->index1 == obj->index2)
{
double ret = (obj->data1[0] + obj->data2[0]);
ret = ret / 2;
return ret;
}
else if (obj->index1 > obj->index2)
return obj->data1[0];
else
return obj->data2[0];
}
void medianFinderFree(MedianFinder* obj) {
free(obj->data1);
free(obj->data2);
}