标签:大顶 nums int 元素 value len 小顶 节点
大顶堆:任意非叶子节点的值大于等于其子节点的值。
小顶堆:任意非叶子节点的值小于等于其子节点的值。
堆是完全二叉树,所以可以直接用数组存储。
堆初始化:
堆的初始化使用筛降法,从最后一个非叶子节点开始向下调整直到跟节点。需要建堆的数组长度为n,最后一个元素的下标为n-1,其父节点为 ((n-1) - 1) >> 1
堆顶元素的删除:
每次只能删除堆顶元素,删除完堆顶元素之后,将最后一个元素放在堆顶,此时的堆不满足堆的性质,需要进行调整。
/** * 向下调整 * * @param i 要调整的编号 */ private void siftDown(int i) { // 如果父节点比任意一个子节点要大,需要调整,和子节点中较小的那个节点进行互换 // 只有非叶子节点才需要调整 int value = nums[i]; while (2 * i + 1 < len) { int left = 2 * i + 1; int right = 2 * i + 2; // 有右节点,先比较两个左右节点 int minValueIdx = (right < len && nums[right] < nums[left]) ? right : left; // 子节点中比较小的和父节点比较 if (nums[minValueIdx] < value) { // 需要调整 nums[i] = nums[minValueIdx]; i = minValueIdx; } else { // 节点i比孩子节点都小,不用再调整了 break; } } nums[i] = value; }
向堆中添加元素:
每次向堆中添加元素时,直接将元素放在末尾,然后调整新放入元素的位置到正确的位置。
public void add(int i) { if (len < nums.length) { nums[len] = i; siftUp(len); len++; } } /** * 向上调整 * * @param i */ private void siftUp(int i) { // i = 0时是根节点, 不需要再调整了 int value = nums[i]; while (i > 0) { int p = (i - 1) >> 1; if (nums[p] > value) { // 父节点更大, 需要调整 nums[i] = nums[p]; i = p; } else { break; } } nums[i] = value; }
标签:大顶,nums,int,元素,value,len,小顶,节点 来源: https://www.cnblogs.com/catpainter/p/12607793.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。