大根堆与小根堆的理解,如何手写一个堆,以及什么时候用自己手写的堆,什么时候用语言提供堆的api,(二者的区别)

本文介绍了大根堆和小根堆的概念,讲解了堆的存储方式,核心操作heapinsert和heapify的原理,以及堆排序的过程。还讨论了何时使用语言自带的堆API与自定义手写堆的区别,特别是在处理引用类型时手写堆的优势,并提出了一种优化的堆实现方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

大根堆与小根堆的理解,如何手写一个堆,以及什么时候用自己手写的堆,什么时候用语言提供堆的api,(二者的区别)

定义

Heap是一种数据结构具有以下的特点:
1)完全二叉树;
2)heap中存储的值是偏序;

Min-heap: 父节点的值小于或等于子节点的值;
Max-heap: 父节点的值大于或等于子节点的值;
用通俗语言来说,大根堆就是每个最大的数字在每个子树的最上方,及大根堆pop值为最大值,小根堆反之
在这里插入图片描述

堆的存储

堆的存储一般由数组表示,由于堆的实质就是完全二叉树,所以对于每个i来说(从0开始),左右孩子分别为2i+1,2i+2,父节点为(i-1)/2,
在这里插入图片描述

堆的核心操作(手写与语言api均有)

heapinsert与heapify
1.heapinsert:加入一个节点,通过上升的方式,依次进行比较,(上升操作),时间复杂度为o(logN)因为树的深度为logN
在这里插入图片描述
swap为交换操作

private void heapInsert(int[] arr, int index) {
   
			while (arr[index] > arr[(index - 1) / 2]) {
   
				swap(arr, index, (index - 1) / 2);
				index = (index - 1) / 2;
			}
		}

2.heapify:弹出根结点之后的,将剩余变成堆的操作(下沉操作),因为弹出根结点后,会将数组最后面的数字顶替为根结点,所以只需将该结点进行下沉操作即可,时间复杂度为o(logN)树的深度为logN
在这里插入图片描述
swap为交换操作

/**
		 * 
		 * @param arr 数组
		 * @param index 索引
		 * @param heapSize 堆大小
		 */
		private void heapify(int[] arr, int index, int heapSize) {
   
			int left = index * 2 + 1;
			while (left < heapSize) {
   
				int largest = left + 1 < heapSize && arr[left + 1] > arr[left] ? left + 1 : left;
				largest = arr[largest] > arr[index] ? largest : index;
				if (largest == index) {
   
					break;
				<
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值