堆与堆排序

堆排序

参考自:链接: link

1 概念

1) 堆的基本概念
堆 是一种特殊的树,满足以下条件即为堆:

  • 首先堆是一个完全二叉树
  • 堆中每一个节点的值都必须大于等于(或小于等于)其左右子节点的值
  • 每个节点都大于等于其子树节点的堆叫“大顶堆“或大根堆,根是最大值
  • 每个节点都小于等于其子树节点的堆叫“小顶堆“或小根堆,根是最小值

因为堆的要求不像二叉搜索树那么严格。他只要求某个节点的子节点大于或小于该节点,因此同一组数据,可以构建多种不同形态的堆:
在这里插入图片描述
2)堆的表示
堆是完全二叉树,大部分时候都是使用数组来存储堆
在这里插入图片描述
规律(根节点是0号)

  • i 结点的父结点 par = floor((i-1)/2) 「向下取整」

  • i 结点的左子结点 2 * i +1

  • i 结点的右子结点 2 * i + 2

因为堆是完全二叉树,所以说,数组中的元素的父节点、孩子节点都是可以用公式算出来的!(层序遍历下)

2 堆的操作

堆的操作主要有两种:插入、删除。。(priority_queue也正是只提供了这两种方法)
在这里插入图片描述

不管是插入还是删除后都有可能不再满足堆的定义即:

  • 堆是一颗完全二叉树

  • 堆中每个节点都必须大于等于(或小于等于)其左右子节点

在插入或删除操作后需要进行调整,让其重新满足堆的特性,这个调整的过程叫做堆化(heapify)

1) 两种堆化方式

从下往上(上浮):当前元素不断向上和父节点比较大小:

  • 大顶堆:当前元素比父节点大,交换,让大的节点上去
  • 小顶堆:当前元素比父节点小,交换,让小的节点上去

在这里插入图片描述

从上往下(下沉):当前元素不断向下和两个孩子节点比较大小

  • 大顶堆:当前元素与子节点中较大的比,比子节点小交换,让小的节点下去
  • 小顶堆:当前元素与子节点中较小的比,比子节点大交换,让大的节点下去

在这里插入图片描述当根节点是0号的时候,下沉和上浮代码是:


//模拟priority_queue
class Heap
{
   
   
private:
    vector<int> vec;
    int capacity;
    int count;


    void swapNode(int i,int j)
    {
   
   
        swap(vec[i],vec[j]);
    }

    //小根堆的上浮操作---在堆中将index节点上浮
    void siftup_minheap(int index)
    {
   
   
        int parentNode=(index-1)/2;
        while(parentNode>=0)
        {
   
   
            if(vec[parentNode]<vec[index])
                break;//父节点比这个节点小,则停止上滤
            
            swapNode(index,parentNode);
            index=parentNode;
            parentNode=(index-1)/2;

        }
    }


    //小根堆的下沉操作--下沉的范围是[index,n),一般是vec.size()
    void siftdown_minheap(int index,int n)
    {
   
   
        int i=index;
        int j=2*i+1;//index节点的左儿子
        while(j<n)
        {
   
   
            if(j+1<n && vec[j+1]<vec[j]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值