小张学算法之数据结构:3.堆

此堆是数据结构中的堆,非我们程序中的堆栈段的堆。堆是一种完全二叉树,即非最后一层其他层全满的树。
分最大堆和最小堆,最小堆,根节点大于孩子节点,左子树右子树也同样如此,是最小堆。
看图
在这里插入图片描述
看这红蓝配色,哈哈我是不会说我是巴萨球迷的哈哈哈。
堆得插入十分简单:只需要在尾部插入,然后调整位置,和父节点比较,通过上浮交换操作,保持堆的特性。
在这里插入图片描述
删除操作:只能删除根节点,然后孩子节点填充位置,段尾节点,填充空缺。
在这里插入图片描述
由于是完全二叉树,可以使用数组来存储,根节点从1开始,2i是其左节点,2i+1是右节点,每次在尾部插入,在头部删除,类似于一个优先级队列
在这里插入图片描述
下标为0的元素,作为缓存位置,之所以从1开始是为了便于计算。

堆代码python实现。


class heapTree:
	def __init__(self, size):
		self.Vector = [None] * (size + 1)
		self.Capacity = size
		self.length = 1
	def print(self):
		if self.length < 2:
			print("")
		this_layer_cnt=1;
		last_cnt=0;
		for i in range(1, self.length):
			print(self.Vector[i], end=' ')
			if  (i-last_cnt) % this_layer_cnt == 0:
				last_cnt = i
				this_layer_cnt *= 2
				print("")
		print("")
	def insert(self, data):
		if self.length >= self.Capacity:
			print("the tree is full!!!")
			return -1
		i = self.length
		self.Vector[i] = data;
		while i >1:
			if self.Vector[i//2] > self.Vector[i]:
				self.Vector[0] =  self.Vector[i//2]
				self.Vector[i//2] = self.Vector[i]
				self.Vector[i] = self.Vector[0]
			i//=2
		self.length += 1
	#delete top
	def delete(self):
		if self.length == 1:
			pass
		elif self.length <= 2:
			self.Vector[1] = None
			self.length = 1
		else:
			i = 1
			#chosse min(lchild,right,last) to fill it
			while i < self.length:
				min_tmp=min(self.Vector, 2*i, 2*i+1, self.length-1)
				self.Vector[i] = min_tmp[0]
				print("---%d,%d", min_tmp)
				if min_tmp[1] == self.length-1:
					break;
				else:
					i = min_tmp[1]
			self.length-=1	

def min(array,i,j,last):
	index = last
	min_tmp = array[last];
	if i < last and array[i] < min_tmp:
		min_tmp=array[i]
		index=i
	if j < last and array[j] < min_tmp:
		min_tmp = array[j]
		index=j
	return (min_tmp,index)

def main():
	hpt = heapTree(100)
	hpt.insert(3)
	hpt.insert(4)
	hpt.insert(2)
	hpt.insert(1)
	hpt.insert(5)
	hpt.insert(8)
	hpt.print()
	hpt.delete()
	hpt.print()

if __name__ == "__main__":
	main()

删除时选择左右孩子和最末尾的元素中最小的一个替换自己。

用途

1.求100w个数据中的前100.
100大;构建一个大小为100的最小堆,然后每个数入堆,如果小于根,则不如堆,如果大于,则入堆,同时将根弹出。其实堆就是优先级队列。100个数,层级为7。每个数,最大比较6次;算法复杂度O(NlogN)。如果想提高速度,可以采用“分治而治”的思想,将这100W个数分成100份,每份求前100,然后,在求这100组的前100混合,求得前100的数就是最终要求。
2. 堆排序
构建堆,然后从堆中pop出来,既是有顺序的数。
3. 双堆
一个最大堆和一个最小堆。用途求中位数,避免排序。左子树最小堆,右子树最大堆,左 > 根 > 右。维持中位数方法,如果大于根,入左树,小于根,入右树,左右子树节点个数相差大于2则,根节点入小树一侧,多的子树的根顶替根节点。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值