堆与优先队列


1.针对的问题:很快的找出最大的元素(最大堆)、很快的找出最小的元素(最小堆)

                         它不适用于从一堆数中检索某一个数

   

   如何去定义一个堆?抓住两点:

   完全二叉树、任何一个内部结点的值大于等于其子节点的值

   一个堆一定是完全二叉树的形式:节约空间、可以很方便的用数组表示

   

  最大堆:根大于等于任何一个子节点(堆排序)

  最小堆:根小于等于任何一个子节点(Krustral)


2.关键操作:shiftdown  和  buildHeap


   如何根据已知的元素建立一个堆?

   核心思想:(以最大堆为例)假设左子树与右子树已经是堆了,如果根的值比左右节点的值都大,则不做任 何改变。否则,选取左右子树中较大的那一个与根交换位置,然后一直shiftdown下去,直到当前已经是叶节点或已经在正确的位 置。


核心代码:

void shiftDown(int pos)//从 pos开始shiftdown
{
	while (!isLeaf(pos))
	{
		int m = 2 * pos + 1, r = 2 * pos + 2;
		if (r<n&&heap[r]>heap[m])
			m = r;
		if (heap[pos] >= heap[m])return;
		else swap(heap, pos, m);

		pos = m;
	}
}

void buildHeap()
{
	for (int i = n / 2 - 1; i >= 0; i--)
		shiftDown(i);
}



  如何在已经建好的堆中插入一个元素?

  核心思想:每次把元素放到数组最后的位置,与父节点比较,如果它的值比父节点的值要大,则与父节点交换位置(shiftup)

   一直shiftup下去,直到已经是根节点或已经在正确的位置

  

void insert(const int& it)
{
	if (n < maxsize)
	{
		int curr = n++;
		heap[curr] = it;

		while (curr != 0 && heap[curr] > heap[parent(curr)])
		{
			swap(heap, curr, parent(curr));
			curr = parent(curr);
		}
	}

}











   

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值