最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

java集合PriorityQueue優(yōu)先級隊列方法實(shí)例

 更新時間:2023年12月20日 10:40:59   作者:bug生產(chǎn)者  
這篇文章主要為大家介紹了java集合PriorityQueue優(yōu)先級隊列方法實(shí)例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

PriorityQueue詳解

PriorityQueue是優(yōu)先級隊列,底層使用數(shù)組存儲,是基于二叉堆的一個無界隊列,可以使用默認(rèn)排序或者提供Comparator比較器使得隊列中的元素有序

存儲結(jié)構(gòu)

小頂堆

根節(jié)點(diǎn)的元素最小是小頂堆(小于左右子節(jié)點(diǎn)的值)

大頂堆

根節(jié)點(diǎn)的元素最大是大頂堆(大于左右子節(jié)點(diǎn)的值)

源碼分析

重要屬性

// 默認(rèn)的初始容量
private static final int DEFAULT_INITIAL_CAPACITY = 11;
/**
 * 使用數(shù)組存放  是一個平衡二叉堆,對于queue[n]有兩個子節(jié)點(diǎn)queue[2*n+1] 和 queue[2*(n+1)]
 */
transient Object[] queue; // non-private to simplify nested class access
/**
 * 優(yōu)先隊列中的元素個數(shù)
 */
private int size = 0;
/**
 * 比較器,如果為null,為使用默認(rèn)的自然排序
 */
private final Comparator<? super E> comparator;
/**
 * 修改次數(shù)
 */
transient int modCount = 0; // non-private to simplify nested class access
/**
* 最大容量
*/
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

構(gòu)造器

public PriorityQueue() {
    this(DEFAULT_INITIAL_CAPACITY, null);
}
public PriorityQueue(int initialCapacity) {
    this(initialCapacity, null);
}
public PriorityQueue(Comparator<? super E> comparator) {
    this(DEFAULT_INITIAL_CAPACITY, comparator);
}
public PriorityQueue(int initialCapacity,
                     Comparator<? super E> comparator) {
    // Note: This restriction of at least one is not actually needed,
    // but continues for 1.5 compatibility
    if (initialCapacity < 1)
        throw new IllegalArgumentException();
    this.queue = new Object[initialCapacity];
    this.comparator = comparator;
}
@SuppressWarnings("unchecked")
public PriorityQueue(Collection<? extends E> c) {
    if (c instanceof SortedSet<?>) {
        SortedSet<? extends E> ss = (SortedSet<? extends E>) c;
        this.comparator = (Comparator<? super E>) ss.comparator();
        initElementsFromCollection(ss);
    }
    else if (c instanceof PriorityQueue<?>) {
        PriorityQueue<? extends E> pq = (PriorityQueue<? extends E>) c;
        this.comparator = (Comparator<? super E>) pq.comparator();
        initFromPriorityQueue(pq);
    }
    else {
        this.comparator = null;
        initFromCollection(c);
    }
}
@SuppressWarnings("unchecked")
public PriorityQueue(PriorityQueue<? extends E> c) {
    this.comparator = (Comparator<? super E>) c.comparator();
    initFromPriorityQueue(c);
}
@SuppressWarnings("unchecked")
public PriorityQueue(SortedSet<? extends E> c) {
    this.comparator = (Comparator<? super E>) c.comparator();
    initElementsFromCollection(c);
}

常用方法

獲取頂端元素

// 直接取數(shù)組中的第一個元素就是頂端元素
public E peek() {
    return (size == 0) ? null : (E) queue[0];
}

插入

以使用默認(rèn)比較器為例

// add方法直接調(diào)用offer方法,往數(shù)組末尾添加元素
public boolean add(E e) {
    return offer(e);
}
public boolean offer(E e) {
  if (e == null)
    throw new NullPointerException();
  modCount++;
  int i = size;
  // 看一下數(shù)組容量是否足夠
  if (i >= queue.length) // 不夠則擴(kuò)容
    grow(i + 1);
  size = i + 1;
  if (i == 0) // 首次添加,將元素放到頂端即可
    queue[0] = e;
  else
    siftUp(i, e);
  return true;
}
// 傳入的minCapacity為插入該數(shù)據(jù)所需要的最小容量
private void grow(int minCapacity) {
  int oldCapacity = queue.length;
  // 如果原始容量小于64,則容量加2,否則容量增加50%
  int newCapacity = oldCapacity + ((oldCapacity < 64) ?
                                   (oldCapacity + 2) :
                                   (oldCapacity >> 1));
  // overflow-conscious code
  if (newCapacity - MAX_ARRAY_SIZE > 0)
    // 如果擴(kuò)容之后的容量大于MAX_ARRAY_SIZE,則比較所需要的容量和MAX_ARRAY_SIZE的大小  
    //(minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE;
    newCapacity = hugeCapacity(minCapacity);
  queue = Arrays.copyOf(queue, newCapacity);
}
private void siftUp(int k, E x) {
  if (comparator != null) // 使用自定義選擇器
    siftUpUsingComparator(k, x);
  else // 使用默認(rèn)的自然排序,默認(rèn)的排序?yàn)樾№敹?
    siftUpComparable(k, x);
}
// 存放數(shù)據(jù)的核心代碼
// k為所要存放的索引位置,x為元素
private void siftUpComparable(int k, E x) {
  Comparable<? super E> key = (Comparable<? super E>) x;
  while (k > 0) {
    int parent = (k - 1) >>> 1; // 左移一位找到父節(jié)點(diǎn)的位置
    Object e = queue[parent];// 父節(jié)點(diǎn)元素
    if (key.compareTo((E) e) >= 0) // 比較該元素和父節(jié)點(diǎn)元素大小,如果該節(jié)點(diǎn)大,則跳出循環(huán)
      break;
    queue[k] = e; // 將父節(jié)點(diǎn)的值存到k索引位置
    k = parent; // 索引位置變成父節(jié)點(diǎn)的索引位置,繼續(xù)對比父節(jié)點(diǎn)的父節(jié)點(diǎn)
  }
  queue[k] = key;
}

刪除

還是以默認(rèn)的比較器為例

public boolean remove(Object o) {
      // 找到該對象對應(yīng)的索引位置
    int i = indexOf(o);
    if (i == -1)
        return false;
    else {
        removeAt(i);
        return true;
    }
}
// 找到該對象對應(yīng)的索引位置
private int indexOf(Object o) {
  if (o != null) {
    for (int i = 0; i < size; i++)
      if (o.equals(queue[i]))
        return i;
  }
  return -1;
}
private E removeAt(int i) {
  // assert i >= 0 && i < size;
  modCount++;
  int s = --size;
  // 尾結(jié)點(diǎn)
  if (s == i) // removed last element
    queue[i] = null;
  else {
    // 尾結(jié)點(diǎn)的元素
    E moved = (E) queue[s];
    // 將尾結(jié)點(diǎn)置空
    queue[s] = null;
    siftDown(i, moved);
    // 沒有進(jìn)while循環(huán)時(表示在siftDown()方法中直接走到queue[k] = key;),刪除節(jié)點(diǎn)沒有子節(jié)點(diǎn),開始向上查找
    // 向上查找的原因是因?yàn)榭赡芩鶆h除的節(jié)點(diǎn)與尾結(jié)點(diǎn)處于不同的子樹下
    if (queue[i] == moved) {
      siftUp(i, moved);
      if (queue[i] != moved)
        return moved;
    }
  }
  return null;
}
// k為所要刪除的元素位置  x為尾結(jié)點(diǎn)元素
private void siftDown(int k, E x) {
  if (comparator != null)
    siftDownUsingComparator(k, x);
  else
    siftDownComparable(k, x);
}
// k為所要移除的索引位置   x為尾結(jié)點(diǎn)元素
// 該方法為從刪除節(jié)點(diǎn)向下查找
private void siftDownComparable(int k, E x) {
  Comparable<? super E> key = (Comparable<? super E>)x;
  // 中間元素,判斷是否有子節(jié)點(diǎn)
  int half = size >>> 1;        // loop while a non-leaf
  while (k < half) {
    // 找到子節(jié)點(diǎn)
    int child = (k << 1) + 1; // assume left child is least
    Object c = queue[child];
    // 找到子節(jié)點(diǎn)的兄弟節(jié)點(diǎn)
    int right = child + 1;
    // 子節(jié)點(diǎn)和子節(jié)點(diǎn)的兄弟節(jié)點(diǎn)中找到小的
    if (right < size &&
        ((Comparable<? super E>) c).compareTo((E) queue[right]) > 0)
      c = queue[child = right];
    // 尾結(jié)點(diǎn)元素小于子節(jié)點(diǎn)元素,結(jié)束循環(huán)
    if (key.compareTo((E) c) <= 0)
      break;
    // 繼續(xù)向下查找
    queue[k] = c;
    k = child;
  }
  //跳出循環(huán)的條件是尾結(jié)點(diǎn)元素大于子節(jié)點(diǎn)元素了,所以將尾結(jié)點(diǎn)元素放到k索引位置
  queue[k] = key;
}
// k為要刪除的索引位置  x為尾結(jié)點(diǎn)元素
private void siftUp(int k, E x) {
  if (comparator != null)
    siftUpUsingComparator(k, x);
  else
    siftUpComparable(k, x);
}
// k為要刪除的索引位置  x為尾結(jié)點(diǎn)元素
// 從刪除索引位置開始向上查找
private void siftUpComparable(int k, E x) {
  Comparable<? super E> key = (Comparable<? super E>) x;
  while (k > 0) {
    // 找到父節(jié)點(diǎn)
    int parent = (k - 1) >>> 1;
    Object e = queue[parent];
    // 尾結(jié)點(diǎn)大于父節(jié)點(diǎn),直接跳出循環(huán)
    if (key.compareTo((E) e) >= 0)
      break;
    // 繼續(xù)向上查找
    queue[k] = e;
    k = parent;
  }
  queue[k] = key;
}

以上就是java集合PriorityQueue優(yōu)先級隊列方法實(shí)例的詳細(xì)內(nèi)容,更多關(guān)于java集合PriorityQueue的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 深度解析Spring Security 中的 SecurityFilterChain核心功能

    深度解析Spring Security 中的 SecurityFilterChain核心功

    SecurityFilterChain通過組件化配置、類型安全路徑匹配、多鏈協(xié)同三大特性,重構(gòu)了Spring Security的配置范式,接下來通過本文給大家介紹Spring Security中的SecurityFilterChain核心功能,感興趣的朋友一起看看吧
    2025-08-08
  • java輸入字符串并將每個字符輸出的方法

    java輸入字符串并將每個字符輸出的方法

    今天小編就為大家分享一篇java輸入字符串并將每個字符輸出的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-07-07
  • mybatis-plus saveOrUpdateBatch踩坑記錄

    mybatis-plus saveOrUpdateBatch踩坑記錄

    這篇文章主要介紹了mybatis-plus saveOrUpdateBatch踩坑記錄,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-12-12
  • 詳解Java中CAS機(jī)制的原理與優(yōu)缺點(diǎn)

    詳解Java中CAS機(jī)制的原理與優(yōu)缺點(diǎn)

    CAS?英文就是?compare?and?swap?,也就是比較并交換,這篇文章主要來和大家介紹一下Java中CAS機(jī)制的原理與優(yōu)缺點(diǎn),感興趣的小伙伴可以了解一下
    2023-06-06
  • java設(shè)計模式-組合模式詳解

    java設(shè)計模式-組合模式詳解

    這篇文章主要介紹了JAVA設(shè)計模式之組合模式,簡單說明了組合模式的原理,并結(jié)合實(shí)例分析了java組合模式的具體用法,需要的朋友可以參考下
    2021-07-07
  • springboot啟動報錯Failed to load class [javax.servlet.Filter]的解決

    springboot啟動報錯Failed to load class [java

    這篇文章主要介紹了springboot啟動報錯Failed to load class [javax.servlet.Filter]的解決方案,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2026-03-03
  • Java中Stream流的map方法示例詳解

    Java中Stream流的map方法示例詳解

    本文給大家介紹Java中Stream流的map方法,包括該方法的定義、語法、示例、注意事項、應(yīng)用場景以及與其他Stream方法的結(jié)合使用,感興趣的朋友跟隨小編一起看看吧
    2026-01-01
  • 通過Feign進(jìn)行調(diào)用@FeignClient?找不到的解決方案

    通過Feign進(jìn)行調(diào)用@FeignClient?找不到的解決方案

    這篇文章主要介紹了通過Feign進(jìn)行調(diào)用@FeignClient?找不到的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • Java中的世界時區(qū)如何自動計算及生成?

    Java中的世界時區(qū)如何自動計算及生成?

    在?Java?中,處理時區(qū)和時間計算是一個非常常見的需求,尤其是在涉及全球應(yīng)用時,Java?提供了一些強(qiáng)大的?API?來處理世界時區(qū)(如?java.time?包),下面將介紹如何基于?Java?自動計算時區(qū)并生成相應(yīng)的時間
    2025-01-01
  • Java反射入門、原理與使用方法詳解

    Java反射入門、原理與使用方法詳解

    這篇文章主要介紹了Java反射入門、原理與使用方法,結(jié)合實(shí)例形式詳細(xì)分析了java反射的概念、原理、使用方法與相關(guān)操作注意事項,需要的朋友可以參考下
    2015-07-07

最新評論

延长县| 托克托县| 喀喇沁旗| 商南县| 黄石市| 茶陵县| 上林县| 彩票| 册亨县| 斗六市| 承德市| 金门县| 安泽县| 普宁市| 綦江县| 北川| 日照市| 行唐县| 咸丰县| 阿图什市| 福州市| 盐边县| 台南县| 海城市| 新和县| 平湖市| 淮阳县| 珠海市| 汉川市| 井研县| 富川| 迁西县| 长治县| 根河市| 泗洪县| 浙江省| 易门县| 涞源县| 叙永县| 海安县| 泾源县|