堆与优先队列


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);
		}
	}

}











   

### Python 中优先队列的概念及用法 #### 一、概念介绍 是一种特殊的树形数据结构,在大多数情况下,这种结构是一棵完全二叉树,并且满足特定性质:对于最大而言,父节点的键总是大于等于子节点;而对于最小,则相反。在Python中,`heapq`模块提供了一个简易接口用于创建最小,这实际上就是一种高效的优先队列实现方式[^5]。 优先队列允许每个元素都有一个关联的优先级,当访问或者移除项目的时候,拥有最高优先级的项目会被最先处理。通过使用`heapq`模块中的函数可以在列表上轻松构建并维护这样的队列,从而实现了O(log n)时间复杂度下的插入和弹出操作效率[^4]。 #### 二、基本操作演示 下面给出了一些常见的基于`heapq`的操作实例: - **初始化空** ```python import heapq as hq min_heap = [] # 创建一个新的最小 hq.heapify(min_heap) # 将列表转换成,默认是最小 ``` - **向中加入新项** ```python item_to_add = (priority_value, task_description) hq.heappush(min_heap, item_to_add) ``` 这里需要注意的是,如果要存储的对象不是简单的数而是元组形式的话,那么比较将会依据第一个元素来进行排序,即这里的`priority_value`决定了项目的顺序[^1]。 - **获取并移除最小/大项** ```python smallest_item = hq.heappop(min_heap) # 返回并删除最小项 ``` 此过程同样保持了剩余部分仍然是有效的结构。 - **替换顶元素而不改变其他任何东西** ```python new_smallest = hq.heapreplace(min_heap, new_item) ``` 该命令相当于连续执行了一次heappop()紧接着一次heappush()[^1]。 #### 三、自定义类作为成员 有时候可能希望把更复杂的对象放入到里边去,比如股票交易记录等。这时可以通过定义自己的类来表示这些实体,并重载其小于运算符以便于正确地按照所需属性进行排序[^3]。 ```python class StockRecord: def __init__(self, ticker, price, share): self.ticker = ticker self.price = price self.share = share def __lt__(self, other): return self.price * self.share < other.price * other.share record_a = StockRecord('AAPL', 150.78, 100) record_b = StockRecord('GOOG', 2900.45, 5) stock_min_heap = [] hq.heappush(stock_min_heap, record_a) hq.heappush(stock_min_heap, record_b) ``` 上述代码片段展示了如何创建一个包含两个不同公司股票信息的最小,其中每条记录都由价格乘以股份数量决定其相对位置。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值