1.二叉堆---A.基础优先级队列

定义:

二叉堆是一种特殊的堆,二叉堆是完全二元树(二叉树)或者是近似完全二元树(二叉树)。二叉堆有两种:最大堆和最小堆。最大堆:父结点的键值总是大于或等于任何一个子节点的键值;最小堆:父结点的键值总是小于或等于任何一个子节点的键值。

使用范围:

读写算法复杂度都是O(logn),是一种相对平衡的数据结构,用于优先级队列,保证头结点最优,之后节点无序,每次获取之后执行树深度重排.

直接上代码–二叉堆实现

package com.zby.calc;

import java.util.Random;

/**
 *
 * 最大堆:比较算法,最大的在上面
 * 最小堆:最小的在上面
 * 算法复杂度O(log n)
 *
 * @author zby
 * @time 2021/6/8 14:36
 * ****************************************
 */
public class A_BinaryHeap<V extends Comparable<V>> {
    private V[] root;
    // 当前容量
    private int size;

    public A_BinaryHeap(V[] root)  {
        this.root = root;
    }
    /**
     *
     * @desc 拿出队列头
     ******************************************
     */
    public V removeTop() {
        V backdata = root[1];
        if(backdata==null)
            return null;
        root[1] = root[size];
        root[size] = null;
        size--;
        sink(1);
        return backdata;
    }
    /**
     * 
     * @desc 插入
     ******************************************
     */
    public void add(V v) {
        size++;
        root[size] = v;
        swim(size);
    }
    /**
     * 
     * @desc 交换对象
     ******************************************
     */
    public void exchangeV(int index1,int index2) {
        V v = root[index1];
        root[index1] = root[index2];
        root[index2] = v;
    }
    /**
     *
     * @desc 下沉
     ******************************************
     */
    public void sink(int index) {
        if(2*index>size)
            return;
        int changeIndex = 2*index;
        if(size>=2*index+1&&root[2*index].compareTo(root[2*index+1])<0)
            changeIndex = 2*index+1;
        if(root[index].compareTo(root[changeIndex])>=0)
            return;
        exchangeV(index,changeIndex);
        sink(changeIndex);
    }
    /**
     *
     * @desc 上浮
     ******************************************
     */
    public void swim(int index) {
        if(index<=1)
            return;
        if(root[index/2].compareTo(root[index])<0) {
            exchangeV(index / 2, index);
            swim(index / 2);
        } else
            return;
    }
    /**
     *
     * @desc main
     ******************************************
     */
    public static void main(String[] args) {
        A_BinaryHeap<Student> ss = new A_BinaryHeap<>(new Student[1000]);
        for (int i = 0; i < 10; i++) {
            ss.add(new Student(new Random().nextInt(1000)));
//            System.out.println("--------------------------------------------");
//            for (int i1 = 0; i1 < ss.root.length; i1++) {
//                Student s = ss.root[i1];
//                if(s==null)
//                    continue;
//                System.out.println(i1+"--------"+s.getIq());
//            }
        }
        System.out.println("拿出数据:");
        for (int j=0;j<100;j++) {
            Student student = ss.removeTop();
            if(student==null)
                continue;
            System.out.println(student.getIq());
        }
    }

    static class Student implements Comparable<Student> {
        int iq;
        public Student(int iq) {
            this.iq = iq;
        }
        public int getIq() {
            return iq;
        }
        public int compareTo(Student o) {
            return this.getIq()-o.getIq();
        }
    }

}

在这里插入图片描述

  1. 当新增一个节点,放在最后,以此往上遍历,上浮到最高的位置.相当于二分查找,数据越多,速度相对更快.
  2. 获取头结点之后,将size位置的根节点填充到头节点 然后开始下沉计算.
  3. 好处在于整颗数放在一个数组里面,父节点当前节点index/2,左子节点2index,右子节点==2index+1,整颗数能快速计算得到结果.
  4. 这种结构适用于插入结果位置随机,不像英雄评分排行榜这种,穿了一件装备加分,但是不足以撼动整棵树,浮动极小,一般上浮或下沉1,2个单位,还有很大概率不会变动,当然也不能得到一个顺序的数据结构.
  5. 总之,只想得到期待值最高的值,然后后续插入变动较大,比较适合.这种只算局部排序,不涉及全场排序.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值