堆的几个基本操作以及堆排序

#include<iostream>
using namespace std;
//堆是一颗完全二叉树,如果父亲结点大于等于孩子结点,那么就是大顶堆;如果父亲结点小于等于孩子结点,那么就是小顶堆
//这里以大顶堆为例
const int maxn=100;
int heap[maxn],n=10;

//向下调整,low指的是欲调整的数组下标,high为最后一个元素的数组下标
void downAdjust(int low,int high)
{
    int i=low,j=i*2;//用j存储左孩子
    while(j<=high)//判断是否有孩子结点,如果没有,则可以跳过
    {
        //判断有没有右孩子,如果右,再判断右孩子和左孩子之间的大小,用j存储较大结点的下标
        if(j+1<=high&&heap[j+1]>heap[j])
        {
            j=j+1;
        }
        //判断孩子结点和父亲结点的大小,如果孩子结点比父亲结点大,那么交换它们的值,接着将要比较的下标移动到它的左孩子
        if(heap[j]>heap[i])
        {
            swap(heap[j],heap[i]);
            i=j;
            j=j*2;
        }
        else
        {
            break;
        }
    }
}

//建堆
//建堆其实就是不断地向下调整,其中只需要将非叶子结点向下调整即可
//在完全二叉树中,非叶子结点的个数为n/2,叶子结点的个数为n-n/2
void createHeap()
{
    for(int i=n/2;i>=1;i--)
    {
        downAdjust(i,n);
    }
}

//删除堆中最大元素(堆顶元素),将堆的最后一个元素覆盖堆顶元素,然后进行向下调整
void deleteTop()
{
    heap[1]=heap[n--];
    downAdjust(1,n);
}

//插入
//将要插入的元素放在堆中的最后一个位置上,然后进行向上调整,直到到堆顶或者父亲结点的权值较大为止
//low一般指的是1,high指的是欲调整结点的数组下标
void upAdjust(int low,int high)
{
    int i=high,j=high/2;
    while(j>=low)//保证父亲结点在堆的范围内
    {
        if(heap[i]>heap[j])
        {
            swap(heap[j],heap[i]);
            i=j;
            j=i/2;
        }
        else
        {
            break;
        }
    }
}
void insert(int x)
{
    heap[++n]=x;
    upAdjust(1,n);
}

//堆排序
//因为建的是大顶堆,所以这里的堆排序就是将它进行从小到大进行排序
void heapsort()
{
    for(int i=n;i>1;i--)
    {
        //堆顶是最大元素,所以将堆顶元素和堆的最后一个元素进行交换
        swap(heap[i],heap[1]);
        //交换完之后,再对堆顶元素进行向下调整
        //最后一个元素是最大的,所以对前面n-1个元素进行调整
        downAdjust(1,i-1);
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值