算法日记(2月17日)-优先队列

优先队列是一种特殊的数据结构,常用于处理需要按优先级排序的元素。本文详细介绍了优先队列的概念,以及如何通过二叉堆来实现。二叉堆是一种堆有序的完全二叉树,其每个节点都大于等于其子节点。插入元素时,新元素会通过上浮操作保持堆的有序性;删除最大值时,会通过下沉操作恢复堆的性质。这种数据结构在算法和数据处理中有着广泛应用。
摘要由CSDN通过智能技术生成

优先队列(Priority queues)

tips:q=++i是将i+1后再赋值给q,i++是先赋原值给q再自加。(这点都忘记的我实在是该剖腹自杀)你要问为什么想起来?那是因为后面代码有简写

什么是优先队列

许多应用程序都需要处理有序的元素,但不一定要求它们全部有序,或是不一定要一次就将它
们排序。很多情况下我们会收集一些元素,处理当前键值最大的元素,然后再收集更多的元素,再
处理当前键值最大的元素。在这种情况下,一个合适的数据结构应该支持两种操作:删除最大元素和插入元素。
 

怎么实现优先队列

数组实现(无序)

数组实现(有序)

链表表示法

二叉堆

定义:当一颗二叉树的每个节点都大于等于它的两个子节点时,被称为堆有序。二叉堆是一组能够用堆有序的完全二叉树排序的元素,并在数组中按照层级储存(不使用数组的第一个位置,应该是方便按照索引计算父节点或者子节点位置)。

表示方法:我们使用完全二叉树来避免使用指针的麻烦,位置k的节点的父节点位置为[k/2],其子节点为2k以及2k+1

堆的算法:在介绍完基础的结构后需要合适的算法来实现功能。堆的比较和交换的实现如下

private boolean less(int i, int j)
{ return pq[i].compareTo(pq[i])<0;}

private void exch(int i, int j)
{ key t = pq[i]; pq[i] = pq[j]; pq[j]=t;}

上浮(swim):由下到上的堆有序化。

private void swim(int k)
{
    while(k>1 && less(k/2, k))//条件是k>1以及子节点对应的元素比父节点小
    {
        exch(k/2, k);//交换父子节点
        k = k/2;//指向下一个父节点,进入判断环节
    }
}

下沉(sink):

private void sink(int k)
{
    while (2*k<=N)//子节点控制在N内
    {
        int j = 2*k;
        if(j<N && less(j, j+1)) j++;//选择子节点里面比较大的那个
        if(!less(k,j)) break;//假如父节点大于子节点,就跳出循环
        exch(k,j);
        k = j;//继续下沉

    }
}

插入元素:

public void insert(Key v)
{
    pq[++N]  = v;// 键值为v,在优先队列的末尾插入这个值
    swim(N);//按照此时的键值来swim上浮
}

删除最大值:

public Key delMax()
{
    Key max = pq[1];//得到最大元素
    exch(1, N--);//与最后个节点交换
    pq[N+1] = null;//防止对象游离?没看懂
    sink(1);//恢复堆的有序性
    return max; 
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值