c语言求中位数的程序,双堆求中位数及C实现

堆的动态创建与删除可参考http://blog.csdn.net/pngynghay/article/details/22101359,此处不再赘述。

双堆求中位数

算法描述:

1、创建两个堆(一个小根堆、一个大根堆),堆大小至少为给定数据个数的一半,(size+1)/2,即向上取整;

2、假定变量mid用来保存中位数,取定第一个元素,赋值给mid,即作为初始的中位数;

3、依次遍历后面的每一个数据,如果比mid小,则插入大根堆;否则插入小根堆;

4、如果大根堆和小根堆上的数据个数相差为2,则将mid插入到元素个数较少的堆中,然后从元素个数较多的堆中删除根节点,并将跟节点赋值给mid;

5、重复步骤3和4,直到所有的数据遍历结束;

此时,mid保存了一个数,再加上两个堆中保存的数,就构成了给定数据的集合。

如果两个堆中元素个数相等,则mid即为最终的中位数;否则,元素较多的堆的根节点元素与mid的和求平均值,即为最终的中位数。

算法实现

算法实现采用了整数,所以,最终的结果取了整数,可以将返回值转换为浮点型,更精确。

uint32_t getmedian(uint32_t *array, uint32_t size)

{

int i = 0, minelem = 0, maxelem = 0;

uint32_t mid = array[0];

uint32_t heapsize = (size+1)/2;

heap_t *minheap = heap_malloc(heapsize);

heap_t *maxheap = heap_malloc(heapsize);

for(i = 1; i < size; i++)

{

if(array[i] < mid)

{

maxheap_insert(maxheap, array[i]);

maxelem++;

}

else

{

minheap_insert(minheap, array[i]);

minelem++;

}

if(minelem - maxelem > 1)

{

maxheap_insert(maxheap, mid);

mid = minheap->element[0];

minheap_delete(minheap);

maxelem++;

minelem--;

}

if(maxelem - minelem > 1)

{

minheap_insert(minheap, mid);

mid = maxheap->element[0];

maxheap_delete(maxheap);

minelem++;

maxelem--;

}

}

printf("\nmaxelem = %d, minelem = %d, pre_mid = %d\n", maxelem, minelem,mid);

if(minelem > maxelem)

{

printf("\nmid[ %d ] = ( mid [ %d ]+minheap->element[0][ %d ] )/2 = %d\n",mid, mid,

minheap->element[0],(mid+minheap->element[0])/2);

mid = (mid+minheap->element[0])/2;

}

if(maxelem < maxelem)

{

printf("\nmid[ %d ] = ( mid [ %d ]+maxheap->element[0][ %d ] )/2 = %d\n",mid, mid,

minheap->element[0],(mid+maxheap->element[0])/2);

mid = (mid+maxheap->element[0])/2;

}

heap_free(minheap);

heap_free(maxheap);

return mid;

}

测试程序

#define NUM 10

int main()

{

uint32_t array[NUM] = {2,20,13,18,15,8,3,5,4,25};

getmedian(array, NUM);

printf("\n");

return 0;

}

测试结果

521420931480cbae0a90d444ff44d05b.png

http://www.dengb.com/Cyy/748129.htmlwww.dengb.comtruehttp://www.dengb.com/Cyy/748129.htmlTechArticle堆 堆的动态创建与删除可参考http://blog.csdn.net/pngynghay/article/details/22101359,此处不再赘述。 双堆求中位数 算法描述: 1、创建两个堆(一个...

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值