国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

關于堆的一切

這篇具有很好參考價值的文章主要介紹了關于堆的一切。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

前置知識

首先給出堆的定義:
堆是一顆樹,滿足堆的性質,即:
對于一個節(jié)點,它的權值大于(或小于)它的各個兒子的權值

有這個性質,顯然
堆的根節(jié)點權值是整個堆中最大或最小的
由此可分為小根堆大根堆

二叉堆

最常見的堆就是二叉堆
二叉堆是一顆滿足堆的性質完全二叉樹
顯然,二叉堆的子樹也是二叉堆

接下來,我們以小根堆為例:

當一個節(jié)點權值小于其父親時,我們嘗試不斷將這個節(jié)點與父親交換,直到其滿足堆的性質
這就是向上調整

同理,
當一個節(jié)點權值大于其父親時,我們嘗試不斷將這個節(jié)點與其兩個兒子中權值較小的一個交換,直到其滿足堆的性質
這就是向下調整

為什么這里要與權值較小的一個交換呢?
因為我們要使交換后滿足堆的性質
所以新的父節(jié)點權值應小于它的兩個兒子

由于堆的高度為 \(\log{n}\)
所以以上兩個操作復雜度顯然為 \(\mathcal {O}(\log{n})\)

那么有了這兩個操作我們就可以完成:
插入(新建節(jié)點然后向上調整)
查詢最大(最?。┲担ǜ?jié)點權值)
刪除最大(最?。┲担ㄅc末尾節(jié)點交換,再向下調整)
刪除任意節(jié)點(與末尾交換,再向上或向下調整,見代碼)
修改任意節(jié)點權值(向上或向下調整)

Luogu (模板)堆

#include<bits/stdc++.h>

using namespace std;

static constexpr int AwA = 1e6 + 10;

inline static int Read() {
    int res = 0;
    bool flag = false;
    int c = getchar();
    while ((c < '0' || c > '9') && ~c) {
        flag |= c == '-';
        c = getchar();
    }
    while (c >= '0' && c <= '9') {
        res = (res << 1) + (res << 3) + (c ^ 48);
        c = getchar();
    }
    return flag ? -res : res;
}

//這里我們認為一個節(jié)點的父親是u<<1,左兒子為u>>1,右兒子為u>>1|1
//根為1
//由堆為完全二叉樹的性質可得只需開一倍數組
int val[AwA];
//儲存總節(jié)點數
int len;

inline void MoveUp(int u) {
    while (u >> 1) {
        int fa = u >> 1;
        if (val[fa] <= val[u]) break;
        swap(val[fa], val[u]);
        u = fa;
    }
}

inline void MoveDown(int u) {
    while (u << 1 <= len) {
        int son = u << 1;
        if (son < len && val[son | 1] < val[son]) son |= 1;
        if (val[u] <= val[son]) break;
        swap(val[u], val[son]);
        u = son;
    }
}

inline int GetTop() { return val[1]; }

inline void Pop() {
    swap(val[1], val[len]);
    len--;
    MoveDown(1);
}

inline void Push(int _val) {
    val[++len] = _val;
    MoveUp(len);
}

//刪除任意已知節(jié)點
inline void Delete(int u) {
    swap(val[u], val[len]);
    len--;
    if (val[u << 1] <= val[u]) MoveDown(u);
    else MoveUp(u);
}

//每次對于根進行向下調整,來合并左右兒子代表的兩個堆
//OIwiki上有證明,這種建樹是O(n)的
inline void Build(int _len, const int *a) {
    len = _len;
    memcpy(val + 1, a + 1, sizeof(int) * len);
    //葉子節(jié)點不調整,減小常數
    for (int i = (len >> 1) - 1; i; i--) MoveDown(i);
}

int main() {
    int n = Read();
    while (n--) {
        int op = Read();
        if (op == 1) Push(Read());
        else if (op == 2) printf("%d\n", GetTop());
        else Pop();
    }
    return 0;
}

此外,對于這段代碼,我們來仔細討論一下:

inline void Build(int _len, const int *a) {
    len = _len;
    memcpy(val + 1, a + 1, sizeof(int) * len);
    for (int i = (len >> 1) - 1; i; i--) MoveDown(i);
}

這段代碼可以在 \(\mathcal {O}(n)\) 時間內建堆
我們按照節(jié)點bfs序倒序向下調整
每當調整到一個節(jié)點時
該節(jié)點的左右兒子所在子樹已然是二叉堆
這時再把根節(jié)點向下調整滿足堆的性質
可視為左右兒子代表的二叉堆的合并

證明:
待補充

可并堆

待補充文章來源地址http://www.zghlxwxcb.cn/news/detail-839335.html

其他堆

待補充

到了這里,關于關于堆的一切的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉載,請注明出處: 如若內容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • 關于差分約束的一切

    本文使用 CC BY-NC-SA 4.0 許可 。 本文為筆者在 OI 學習中的復習向學習筆記。 部分內容會比較簡略。 如有好的習題會不斷補充。 差分約束 解決這樣一類問題: 給定一個 n 元一次不等式組,讓你求出一組解/判定是否有解/算出某個數的最值/算出和的最值…… 先從最簡單的開始

    2024年04月09日
    瀏覽(17)
  • 關于樹的直徑的一切

    本文使用 CC BY-NC-SA 4.0 許可 。 本文為筆者在 OI 學習中的復習向學習筆記。 部分內容會比較簡略。 如有好的習題會不斷補充。 以下部分詳細證明可見 OI Wiki 。 樹的直徑 指樹上任意兩點間距離的最大值。 先以任意點為根找到最遠點 (v) 。 再以 (v) 為根找到最遠點 (u) 。

    2024年04月08日
    瀏覽(36)
  • 關于基環(huán)樹的一切

    本文使用 CC BY-NC-SA 4.0 許可 。 本文為筆者在 OI 學習中的復習向學習筆記。 部分內容會比較簡略。 如有好的習題會不斷補充。 基環(huán)樹 是一個有 (n) 個點 (n) 條邊的連通圖。 因為 樹 有 (n) 個點 (n-1) 條邊。 所以基環(huán)樹可以看作是加了一條邊的樹。 那么也就是 加了個環(huán)的

    2024年04月08日
    瀏覽(17)
  • 【算法】關于排序你應該知道的一切(上)

    【算法】關于排序你應該知道的一切(上)

    和光同塵_我的個人主頁 單程孤舟,出云入霞,如歌如吟。 --門孔 國慶快樂??!本來想把排序都做到一起的,才寫了一半就八千多字了,那就分開發(fā)吧,一如既往的詳細哦?? 排序 :所謂排序,就是使一串記錄,按照其中的某個或某些的大小,遞增或遞減的排列起來

    2024年02月06日
    瀏覽(20)
  • 【算法】關于排序你應該知道的一切(下)

    【算法】關于排序你應該知道的一切(下)

    和光同塵_我的個人主頁 單程孤舟,出云入霞,如歌如吟。 --門孔 啊還是國慶快樂!上節(jié)介紹了較為簡單的插入排序、選擇排序,今天我們上強度,學習交換排序、歸并排序還有計數排序,開沖?? 2.1.1. 基本思想 關于冒泡排序我們在C語言的學習中就有涉及 依次比較序列中相

    2024年02月07日
    瀏覽(22)
  • 【數據結構】關于排序你應該知道的一切(下)

    【數據結構】關于排序你應該知道的一切(下)

    和光同塵_我的個人主頁 單程孤舟,出云入霞,如歌如吟。 --門孔 啊還是國慶快樂!上節(jié)介紹了較為簡單的插入排序、選擇排序,今天我們上強度,學習交換排序、歸并排序還有計數排序,開沖?? 2.1.1. 基本思想 關于冒泡排序我們在C語言的學習中就有涉及 依次比較序列中相

    2024年02月05日
    瀏覽(19)
  • 我們所知道的關于 OpenAI 的 ChatGPT 的一切

    我們所知道的關于 OpenAI 的 ChatGPT 的一切

    如果您還沒有聽說過ChatGPT,這是來自人工智能實驗室 OpenAI 的不可思議的新聊天機器人,這里是您需要了解的有關這個有爭議的新程序的所有信息的快速入門。 ChatGPT 是一種人工智能工具,允許用戶生成原始文本。你可以問它問題,給它創(chuàng)造性的提示,并用它來生成一大堆不

    2023年04月13日
    瀏覽(25)
  • (一) AIGC了解+前置知識

    大論文雙盲意見還沒回來,每天度日如年,慌的一批,唯恐延畢,得找點事情干~ 小論文major revision,本來打算一鼓作氣把小論文完全改好的,但是搞了三個月的文字工作,好久沒有吸收新知識了 所以…每天邊學新東西,邊改小論文~ 最近AIGC比較火,就從它開始吧 AIGC大致了解

    2024年02月13日
    瀏覽(18)
  • 7.前置知識3:LoadBalance

    https://medium.com/google-cloud/understand-cloud-load-balancer-like-a-senior-engineer-d4f55f3111fc 負載均衡本來是個硬件設備。其實一開始確實是的,然而現在已經不同了。 尤其是云廠商提供的負載均衡方案幾乎全部是靠軟件?,F在的負載均衡不僅是網絡流量復雜均衡,幾乎所有的平衡多個計算資

    2024年02月20日
    瀏覽(19)
  • JUC前置知識

    JUC概述 在開發(fā)語言中,線程部分是重點,JUC是關于線程的。JUC是java.util.concurrent工具包的簡稱。這是一個處理線程的工具包,JDK1.5開始出現的。 線程和進程 線程和進程的概念 進程(process): 是計算機的程序關于某數據集合上的一次允許活動,是操作系統(tǒng)進行資源分配和任務調

    2024年02月08日
    瀏覽(19)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包