1.sift-up
假定对于某个i>1,H[i]变成了键值大于它父节点键值的元素,这样就违反了堆的特性。我们需要使用Sift-up运算把新的数据项移到在二叉树中适合它的位置上。
Sift-up的运算沿着从H[i]到根节点的唯一一条路径,把H[i]移到适合它的位置上。在沿着路径的每一步上,都将H[i]键值和它父节点的键值H[⌊i/2⌋]相比较。
常用于:插入操作
代码:
void sift-up ( MaxHeap H)
{
i = H->size;
item = H->Element [i];
for ( ; H -> Element [ i/2 ] < item; i /= 2 ) // 与父结点做比较,i / 2 表示的就是父结点的下标
H -> Element [ i ] = H -> Element [ i/2 ]; // 向下过滤结点
H -> Element [ i ] = item ; //若for循环完成后,i更新为父节点i,然后将 item 插入
}
放在堆的插入里就是:
void Insert ( MaxHeap H,int item )
{
// 将元素item插入最大堆H,其中H -> Elements [0] 已经定义为哨兵
int i ;
if ( H->Size ==1000 )
{
printf ( "最大堆已满" );
return ;
}
i = ++H -> Size ; // i 指向插入后堆中的最后一个元素的位置
for ( ; H -> Element [ i/2 ] < item; i /= 2 ) // 与父结点做比较,i / 2 表示的就是父结点的下标
H -> Element [ i ] = H -> Element [ i/2 ]; // 向下过滤结点
H -> Element [ i ] = item ; //若for循环完成后,i更新为父节点i,然后将 item 插入
for(i = 1 ; i <= H->Size; i++)
{
printf("%d", H->Element[i]);
}
printf("\n");
}
2.Sift-down
假定对于i ≤ ⌊n/2⌋,存储在H[i]中元素的键值变成小于H[2i]和H[2i+1]中的最大值(如果2i+1存在的话),这样也违反了堆的特性。Sift-down运算使H[i]“渗”到二叉树中适合它的位置上,沿着这条路径的每一步,都把H[i]的键值和存储在它子节点(如果存在)中的两个键值里最大的那个相比较。
过程 Sift-down
输入 数组H[1...n]和位于1和n之间的索引i
输出 下移H[i](如果需要),以使它不小于子节点
常用于删除操作,调整堆
这里以我上篇博客为例,代码如下:
sift-down(i)
{
int j, item;
for(; i*2<=m ;i = j)
{
j = 2 * i;
if(j!=m&&h[j]>h[j+1])
{
j++;
}
if(h[i]>h[j])
swap(i, j);
else
{
break;
}
}
}
删除代码为:(代码比较冗长,可以进行优化)
int DeleteMax( MaxHeap H )
{
/* 从最大堆H中取出键值为最大的元素,并删除一个结点 */
int Parent, Child;
int MaxItem, temp;
if (H->Size == 0)
{
printf("最大堆已为空");
return;
}
MaxItem = H->Element[1]; /* 取出根结点最大值 */
/* 用最大堆中最后一个元素从根结点开始向上过滤下层结点 */
H->Element[1] = H->Element[H->Size--];
temp = H->Element[1];
for( Parent=1; Parent*2<=H->Size; Parent=Child )
{
Child = Parent * 2;//child指向根下层元素的左节点
if( (Child!= H->Size) &&
(H->Element[Child] < H->Element[Child+1]) )
Child++; //Child指向左右子结点的较大者
if( temp >= H->Element[Child] ) break;//如果比较大的节点元素还大,就可以将temp元素放在树根
else //移动temp元素到下一层
swap(H, Parent,Child);//将儿子元素移到树根,temp再和下层元素作比较
}
int i;
for(i = 1 ; i <= H->Size; i++)
{
printf("%d", H->Element[i]);
}
printf("\n");
return MaxItem;
}
Sift-down 可以用于由数组建立堆(最小最大)
详情请看我上一篇博客https://blog.csdn.net/Kaka_chake/article/details/81626385