刪除 最小(最大)堆第k個元素

添加一個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;
	
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章