当前位置:网站首页>堆(優先級隊列)
堆(優先級隊列)
2022-07-02 12:07:00 【菜菜不恰菜】
目錄
🥬堆的性質

總結:一顆完全二叉樹以層序遍曆方式放入數組中存儲,這種方式的主要用法就是堆的錶示。
🥬堆的分類

🥬堆的向下調整
現在有一個數組,邏輯上是完全二叉樹,我們通過從根節點開始的向下調整算法可以把它調整成一個小堆或者大堆。向下調整算法有一個前提:左右子樹必須是一個堆,才能調整。
以小堆為例:
1、先讓左右孩子結點比較,取最小值。
2、用較小的那個孩子結點與父親節點比較,如果孩子結點<父親節點,交換,反之,不交換。
3、循環往複,如果孩子結點的下標越界,則說明已經到了最後,就結束。
代碼示例:
//parent: 每棵樹的根節點
//len: 每棵樹的調整的結束比特置
public void shiftDown(int parent,int len){
int child=parent*2+1; //因為堆是完全二叉樹,沒有左孩子就一定沒有右孩子,所以最起碼是有左孩子的,至少有1個孩子
while(child<len){
if(child+1<len && elem[child]<elem[child+1]){
child++;//兩孩子結點比較取較小值
}
if(elem[child]<elem[parent]){
int tmp=elem[parent];
elem[parent]=elem[child];
elem[child]=tmp;
parent=child;
child=parent*2+1;
}else{
break;
}
}
}
🥬堆的建立
public void creatHeap(int[] arr){
for(int i=0;i<arr.length;i++){
elem[i]=arr[i];
useSize++;
}
for(int parent=(useSize-1-1)/2;parent>=0;parent--){//數組下標從0開始
shiftDown(parent,useSize);
}
}
建堆的空間複雜度為O(N),因為堆為一棵完全二叉樹,滿二叉樹也是一種完全二叉樹,我們用滿二叉樹(最壞情况下)來證明。
🥬堆得向上調整
現在有一個堆,我們需要在堆的末尾插入數據,再對其進行調整,使其仍然保持堆的結構,這就是向上調整。
以大堆為例:
代碼示例:
public void shiftup(int child){
int parent=(child-1)/2;
while(child>0){
if(elem[child]>elem[parent]){
int tmp=elem[parent];
elem[parent]=elem[child];
elem[child]=tmp;
child=parent;
parent=(child-1)/2;
}else{
break;
}
}
}
🥬堆的常用操作
入隊列
往堆裏面加入元素,就是往最後一個比特置加入,然後在進行向上調整。
public boolean isFull(){
return elem.length==useSize;
}
public void offer(int val){
if(isFull()){
elem= Arrays.copyOf(elem,2*elem.length);//擴容
}
elem[useSize++]=val;
shiftup(useSize-1);
}
出隊列
把堆裏元素删除,就把堆頂元素和最後一個元素交換,然後向整個數組大小减一,最後向下調整,就删除了棧頂元素。
public boolean isEmpty(){
return useSize==0;
}
public int poll(){
if(isEmpty()){
throw new RuntimeException("優先級隊列為空");
}
int tmp=elem[0];
elem[0]=elem[useSize-1];
elem[useSize-1]=tmp;
useSize--;
shiftDown(0,useSize);
return tmp;
}
獲取隊首元素
public int peek() {
if (isEmpty()) {
throw new RuntimeException("優先級隊列為空");
}
return elem[0];
}
🥬TopK 問題
給你6個數據,求前3個最大數據。這時候我們用堆怎麼做的?
解題思路:
1、如果求前K個最大的元素,要建一個小根堆。
2、如果求前K個最小的元素,要建一個大根堆。
3、第K大的元素。建一個小堆,堆頂元素就是第K大的元素。
4、第K小的元素。建一個大堆,堆頂元素就是第K大的元素。
舉個例子:求前n個最大數據
代碼示例:
public static int[] topK(int[] array,int k){
//創建一個大小為K的小根堆
PriorityQueue<Integer> minHeap=new PriorityQueue<>(k, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o1-o2;
}
});
//遍曆數組中元素,將前k個元素放入隊列中
for(int i=0;i<array.length;i++){
if(minHeap.size()<k){
minHeap.offer(array[i]);
}else{
//從k+1個元素開始,分別和堆頂元素比較
int top=minHeap.peek();
if(array[i]>top){
//先彈出後存入
minHeap.poll();
minHeap.offer(array[i]);
}
}
}
//將堆中元素放入數組中
int[] tmp=new int[k];
for(int i=0;i< tmp.length;i++){
int top=minHeap.poll();
tmp[i]=top;
}
return tmp;
}
public static void main(String[] args) {
int[] array={12,8,23,6,35,22};
int[] tmp=topK(array,3);
System.out.println(Arrays.toString(tmp));
}
結果:
數組排序
再者說如果要對一個數組進行從小到大排序,要借助大根堆還是小根堆呢?
---->大根堆
代碼示例:
public void heapSort(){
int end=useSize-1;
while(end>0){
int tmp=elem[0];
elem[0]=elem[end];
elem[end]=tmp;
shiftDown(0,end);//假設這裏向下調整為大根堆
end--;
}
}
🥬小結
以上就是今天的內容了,有什麼問題可以在評論區留言
边栏推荐
- 数据分析 - matplotlib示例代码
- qt 仪表自定义控件
- The most understandable f-string tutorial in history, collecting this one is enough
- Natural language processing series (I) -- RNN Foundation
- conda常用命令汇总
- Leetcode922 按奇偶排序数组 II
- Jenkins用户权限管理
- PHP 2D and multidimensional arrays are out of order, PHP_ PHP scrambles a simple example of a two-dimensional array and a multi-dimensional array. The shuffle function in PHP can only scramble one-dim
- PgSQL string is converted to array and associated with other tables, which are displayed in the original order after matching and splicing
- 机械臂速成小指南(七):机械臂位姿的描述方法
猜你喜欢
[QT] Qt development environment installation (QT version 5.14.2 | QT download | QT installation)
SVO2系列之深度濾波DepthFilter
GGPUBR: HOW TO ADD ADJUSTED P-VALUES TO A MULTI-PANEL GGPLOT
Data analysis - Matplotlib sample code
Read the Flink source code and join Alibaba cloud Flink group..
(C语言)输入一行字符,分别统计出其中英文字母、空格、数字和其它字符的个数。
【2022 ACTF-wp】
How to Easily Create Barplots with Error Bars in R
SVO2系列之深度滤波DepthFilter
自然语言处理系列(一)——RNN基础
随机推荐
YYGH-9-预约下单
Yygh-9-make an appointment to place an order
基于Arduino和ESP8266的连接手机热点实验(成功)
Test shift left and right
排序---
(C语言)输入一行字符,分别统计出其中英文字母、空格、数字和其它字符的个数。
H5,为页面添加遮罩层,实现类似于点击右上角在浏览器中打开
Small guide for rapid formation of manipulator (VII): description method of position and posture of manipulator
From scratch, develop a web office suite (3): mouse events
to_bytes与from_bytes简单示例
From scratch, develop a web office suite (3): mouse events
Maximum profit of jz63 shares
ES集群中节点与分片的区别
Cmake cross compilation
时间格式化显示
Time format display
Analyse de l'industrie
Enter the top six! Boyun's sales ranking in China's cloud management software market continues to rise
还不会安装WSL 2?看这一篇文章就够了
This article takes you to understand the operation of vim