堆分为两种,大根堆:任何一个子树的根节点是子树中的最大值 。小根堆:任何一个子树的根节点是是子树的最小值。应用堆结构解决贪心问题很有效果,具体方法后续再更新。
对堆结构的两种操作:
heapinsert:插入一个新节点,调整建堆。
void heapinsert(int arr[],int index)
{

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

}
插入一个新节点的时间复杂度:假设堆有N个节点,则层数为logN,最坏情况下,从最后一层向上一直向上调整到根节点。所以时间复杂度为logN。

heapify:i位置的值发生变化,并且是变小,调整成大根堆。
void heapify(int a[],int i,int size)//size为大根堆的大小
{
int L=i*2+1;
while(L<大根堆的大小)
{

    int  largest=L+1<size&&arr[L]>arr[L+1]?L:L+1;//如果右节点在堆范围内,判断两个子节点哪一个更大,
    int largest=arr[largest]>a[i]?largest:i;      //判断父节点和较大子节点哪一个更大
    if(largest==i)        //如果最大的就是当前节点,则,不用下沉
    break;
    swap(arr,largest,i);//否则交换两个节点的值
    i=largest;   //令largest等于i
    L=i*2+1:  //寻找新的左子节点
      }

}
调整时间复杂度,最坏情况从根节点一直沉到底,o(logN);

运用案例:一组数据不断的吐出一些数字,要你求出已经吐出的数字中的中位数
方法:建立一个大根堆,在建立一个小根堆,吐出的数字不断加入大根堆,调整建堆,如果大根堆中的数字总和与小根堆中数字总和大于1;则取大根堆堆顶元素加入小根堆。这样吐出的数字总会被分成各N/2份,大根堆中数字永远是,较小的前半部分,小根堆中的数字永远是较大的后半部分,中位数可以求出了。

堆排序:
先生成大根堆,然后堆顶元素在和数组最后一个元素交换位置,同时堆的范围size-1;重复以上操作。
代码
for(int i=0;i<数组长度;i++)
heapinsert(arr,i); //相当于从i=0开始插入新节点进行建堆
int size=arr.length;
swap(arr,0,–size); //交换堆顶元素数组最后一个元素
while(size>0)
{
heapify(arr,0,size); //将打乱的堆重新建成堆
swap(arr,0,–size); //交换建堆后的堆顶元素和数组倒数的第(2,3,4.。。。。)元素
}

此外建堆,还有一种从叶子结点向根节点,从下往上的建堆方法,下次再更新

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值