数据结构--优先级队列

1.无序数组实现

要点

        入队保持顺序

        出队前找到优先级最高的出队,相当于一次选择排序

public class PriorityQueue1<E extends Priority> implements Queue<E> {

    Priority[] array;
    int size;

    public PriorityQueue1(int capacity) {
        array = new Priority[capacity];
    }

    @Override // O(1)
    public boolean offer(E e) {
        if (isFull()) {
            return false;
        }
        array[size++] = e;
        return true;
    }

    // 返回优先级最高的索引值
    private int selectMax() {
        int max = 0;
        for (int i = 1; i < size; i++) {
            if (array[i].priority() > array[max].priority()) {
                max = i;
            }
        }
        return max;
    }

    @Override // O(n)
    public E poll() {
        if (isEmpty()) {
            return null;
        }
        int max = selectMax();
        E e = (E) array[max];
        remove(max);
        return e;
    }

    private void remove(int index) {
        if (index < size - 1) {
            System.arraycopy(array, index + 1,
                    array, index, size - 1 - index);
        }
        array[--size] = null; // help GC
    }

    @Override
    public E peek() {
        if (isEmpty()) {
            return null;
        }
        int max = selectMax();
        return (E) array[max];
    }

    @Override
    public boolean isEmpty() {
        return size == 0;
    }

    @Override
    public boolean isFull() {
        return size == array.length;
    }
}

2.有序数组实现

要点

        入队后排好序,优先级最高的排列在尾部

        出队只需删除尾部元素即可

public class PriorityQueue2<E extends Priority> implements Queue<E> {

    Priority[] array;
    int size;

    public PriorityQueue2(int capacity) {
        array = new Priority[capacity];
    }

    // O(n)
    @Override
    public boolean offer(E e) {
        if (isFull()) {
            return false;
        }
        insert(e);
        size++;
        return true;
    }

    // 一轮插入排序
    private void insert(E e) {
        int i = size - 1;
        while (i >= 0 && array[i].priority() > e.priority()) {
            array[i + 1] = array[i];
            i--;
        }
        array[i + 1] = e;
    }

    // O(1)
    @Override
    public E poll() {
        if (isEmpty()) {
            return null;
        }
        E e = (E) array[size - 1];
        array[--size] = null; // help GC
        return e;
    }

    @Override
    public E peek() {
        if (isEmpty()) {
            return null;
        }
        return (E) array[size - 1];
    }

    @Override
    public boolean isEmpty() {
        return size == 0;
    }

    @Override
    public boolean isFull() {
        return size == array.length;
    }
}

3.堆实现

计算机科学中,堆是一种基于树的数据结构,通常用完全二叉树实现。堆的特性如下

        最顶层的节点(没有父亲)称之为 root 根节点

        在大顶堆中,父节点的值大于或等于其子节点的值。

        在小顶堆中,父节点的值小于或等于其子节点的值。

        堆总是完全二叉树,即除了最后一层可能不满外,其余层都必须填满节点,最后一层的节点都是从左到右排列的。

例1 - 满二叉树(Full Binary Tree)特点:每一层都是填满的

例2 - 完全二叉树(Complete Binary Tree)特点:最后一层可能未填满,靠左对齐

例3 - 大顶堆

                   

例4 - 小顶堆

                   

完全二叉树可以使用数组来表示

                          ​

特征

  • 如果从索引 0 开始存储节点数据

    • 节点 i 的父节点为 floor((i-1)/2),当 i>0 时

    • 节点 i 的左子节点为 2i+1,右子节点为 2i+2,当然它们得 < size

  • 如果从索引 1 开始存储节点数据

    • 节点 i 的父节点为 floor(i/2),当 i > 1 时

    • 节点 i 的左子节点为 2i,右子节点为 2i+1,同样得 < size

    • public class PriorityQueue4<E extends Priority> implements Queue<E> {
      
          Priority[] array;
          int size;
      
          public PriorityQueue4(int capacity) {
              array = new Priority[capacity];
          }
      
          @Override
          public boolean offer(E offered) {
              if (isFull()) {
                  return false;
              }
              int child = size++;
              int parent = (child - 1) / 2;
              while (child > 0 && offered.priority() > array[parent].priority()) {
                  array[child] = array[parent];
                  child = parent;
                  parent = (child - 1) / 2;
              }
              array[child] = offered;
              return true;
          }
      
      
          private void swap(int i, int j) {
              Priority t = array[i];
              array[i] = array[j];
              array[j] = t;
          }
      
          @Override
          public E poll() {
              if (isEmpty()) {
                  return null;
              }
              swap(0, size - 1);
              size--;
              Priority e = array[size];
              array[size] = null;
              
              shiftDown(0);        
              return (E) e;
          }
      
          void shiftDown(int parent) {
              int left = 2 * parent + 1;
              int right = left + 1;
              int max = parent;
              if (left < size && array[left].priority() > array[max].priority()) {
                  max = left;
              }
              if (right < size && array[right].priority() > array[max].priority()) {
                  max = right;
              }
              if (max != parent) {
                  swap(max, parent);
                  shiftDown(max);
              }
          }
      
          @Override
          public E peek() {
              if (isEmpty()) {
                  return null;
              }
              return (E) array[0];
          }
      
          @Override
          public boolean isEmpty() {
              return size == 0;
          }
      
          @Override
          public boolean isFull() {
              return size == array.length;
          }
      }

                        以上这些笔记是我从黑马程序员2023年最新的数据结构教程中整理出来的,并非我本人所创,发表是为了将自己所学的内容进行巩固,也帮助大家进行知识梳理

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ray-国

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值