题目描述:
求中位数。
解题思路:
用两个堆来记录中间的两位数。一个大根堆,一个小根堆。变动堆的最后一个数采用倒调整操作(这里代码可以改进成倒调序,另写一个函数效率会更高些)。变动根值采用正调整操作。本题对时间要求较严,时间复杂度不能超过nlogn。
代码:
#include <stdio.h>
#include <stdlib.h>
#define N 100001
#define MAX 1
#define MIN 0
double array[N];
double left_heap[N], right_heap[N];
int lcnt, rcnt;
void heap_adjust(double a[N], int cnt, int f)
{
int l = 2*cnt, r=2*cnt+1, largest = cnt;
double tmp;
if( f==MAX )
{
if(l<=lcnt && a[l] > a[cnt])
largest = l;
if(r<=lcnt && a[r] > a[largest])
largest = r;
}
else
{
if(l<=rcnt && a[l] < a[cnt])
largest = l;
if(r<=rcnt && a[r] < a[largest])
largest = r;
}
// printf("f=%d, largest=%d.\n",f,largest);
if(largest != cnt)
{
tmp = a[largest];
a[largest] = a[cnt];
a[cnt] = tmp;
heap_adjust(a, largest, f);
}
}
main()
{
int n, count, op, i;
double num;
while(scanf("%d",&n)!=EOF)
{
count = 0;
lcnt = 0;
rcnt = 0;
while(n>0)
{
n--;
scanf("%d",&op);
if(1 == op)
{
count ++;
scanf("%lf",&num);
if(1 == count)
left_heap[++lcnt] = num;
else if(2 == count)
{
if(num >= left_heap[lcnt])
right_heap[++rcnt] = num;
else
{
right_heap[++rcnt] = left_heap[lcnt];
left_heap[lcnt] = num;
}
}
else
{
if(num>left_heap[1] && rcnt-lcnt < 1) //加入小根堆-右
{
rcnt ++;
right_heap[rcnt] = num;
for(i=rcnt/2;i>=1;i=i/2)
heap_adjust(right_heap, i, MIN);
}
else if(num<right_heap[1] && lcnt-rcnt < 1)//加入大根堆-左
{
lcnt ++;
left_heap[lcnt] = num;
for(i=lcnt/2;i>=1;i=i/2)
heap_adjust(left_heap, i, MAX);
}
else if(num>=right_heap[1] && rcnt-lcnt == 1) //把小根堆头挪到大根堆,把num放入小根堆
{
lcnt++;
left_heap[lcnt] = right_heap[1];
for(i=lcnt/2;i>=1;i=i/2)
heap_adjust(left_heap,i, MAX);
right_heap[1] = num;
heap_adjust(right_heap,1, MIN);
}
else
{
rcnt++;
right_heap[rcnt] = left_heap[1];
for(i=rcnt/2;i>=1;i=i/2)
heap_adjust(right_heap, i, MIN);
left_heap[1] = num;
heap_adjust(left_heap, 1, MAX);
}
}
// //print heap
// printf("left heap:\n");
// for(i=1;i<=lcnt;i++)
// printf("%.1f\t",left_heap[i]);
// printf("\n");
// printf("right_heap:\n");
// for(i=1;i<=rcnt;i++)
// printf("%.1f\t",right_heap[i]);
// printf("\n");
}
else
{
if( count%2 ==0 )
printf("%.1f\n",(left_heap[1]+right_heap[1])/2);
else
{
if(lcnt > rcnt)
printf("%.1f\n",left_heap[1]);
else
printf("%.1f\n",right_heap[1]);
}
}
}
}
system("pause");
return 0;
}