添加一個idx,每次改變堆上元素位置的時候,實時更新元素的位置;刪除第k個元素的時候,相當在以第k個元素爲根節點的子樹裏面,把根節點 pop出來。
示例代碼如下:
struct package
{
int pid;
int price;
int idx;
};
struct package g_package[100];
int g_idx;
struct package *g_queue[100];
int g_queue_size;
struct package *getPackage(int pid, int price)
{
struct package *ret = &g_package[g_idx++];
ret->pid = pid;
ret->price = price;
return ret;
}
void push(struct package *p)
{
int i = g_queue_size++;
while(i > 0)
{
int j = (i-1)/2;
if( g_queue[j]->price <= p->price)
{
break;
}
g_queue[i] = g_queue[j];
g_queue[i]->idx = i;
i = j;
}
g_queue[i] = p;
g_queue[i]->idx = i;
}
struct package *pop(void)
{
struct package *ret = g_queue[0];
struct package *p = g_queue[--g_queue_size];
int i = 0;
while( 2 * i + 1 < g_queue_size)
{
int a = 2 * i + 1;
int b = 2 * i + 2;
struct package *pMin = g_queue[a];
if(b < g_queue_size)
{
if(pMin->price > g_queue[b]->price)
{
pMin = g_queue[b];
}
a = b;
}
if(pMin->price >= p->price)
{
break;
}
g_queue[i] = pMin;
g_queue[i]->idx = i;
i = b;
}
g_queue[i] = p;
g_queue[i]->idx = i;
return ret;
}
void delete(int idx)
{
struct package *p = g_queue[idx];
struct package *tmp = g_queue[--g_queue_size];
int i = idx;
while( 2 * i + 1 < g_queue_size)
{
int a = 2 * i + 1;
int b = 2 * i + 2;
struct package *pMin = g_queue[a];
if(b < g_queue_size)
{
if(g_queue[b]->price < pMin->price)
{
pMin = g_queue[b];
a = b;
}
}
if(pMin->price >= tmp->price)
{
break;
}
g_queue[i] = pMin;
g_queue[i]->idx = i;
i = a;
}
g_queue[i] = tmp;
g_queue[i]->idx = i;
}
int main(void)
{
push( getPackage(100, 209));
push( getPackage(20, 100));
push( getPackage(80, 5));
push( getPackage(9, 30));
push( getPackage(878, 1));
push( getPackage(999, 1900));
push( getPackage(99, 15));
push( getPackage(21, 23));
push( getPackage(1, 18));
push( getPackage(3, 37));
delete(3);
return 0;
}