React 第三十七章 Scheduler 最小堆算法

在 Scheduler 中,使用最小堆的數據結構在對任務進行排序。

// 兩個任務隊列
var taskQueue: Array<Task> = []; 
var timerQueue: Array<Task> = [];push(timerQueue, newTask); // 像數組中推入一個任務
pop(timerQueue); // 從數組中彈出一個任務
timer = peek(timerQueue); // 從數組中獲取第一個任務

我們在學習 Scheduler 中最小堆算法之前,需要先了解什么是 二叉堆。

二叉堆

二叉堆是一種基于完全二叉樹的數據結構,它滿足堆屬性:對于每個節點x,x的父節點的值小于等于x的值(最小堆)或者大于等于x的值(最大堆)。

根據二叉堆的定義我們發現一個名次 完全二叉樹。,完全二叉樹是對二叉樹完全樹的一種特殊情況。

下面我們來了解什么是二叉樹完全樹

二叉樹

二叉樹是一種特殊的樹結構,它的每個節點最多有兩個子節點,稱為左子節點和右子節點。例如下圖:

image-20221230135103093

完全樹

所謂完全樹,指的是一棵樹再進行填寫的時候,遵循的是“從左往右,從上往下”

例如下面的這些樹,就都是完全樹:

image-20221230135524942

完全樹中的數值

可以分為兩大類:

  • 最大堆:父節點的數值大于或者等于所有的子節點
  • 最小堆:剛好相反,父節點的數值小于或者等于所有的子節點

最大堆示例:

image-20221230140218584

最小堆示例:

image-20221230140339328
  • 無論是最大堆還是最小堆,第一個節點一定是這個堆中最大的或者最小的
  • 每一層不是按照一定順序來排列的,比如下面的例子,6可以在左分支,3可以在右分支
image-20221230140935130
  • 每一層的所有元素不一定比下一層(非自己的子節點)大或者小

二叉堆主要有兩種類型:

最小堆:對于每個節點x,x的值小于等于它的左子節點和右子節點的值。
最大堆:對于每個節點x,x的值大于等于它的左子節點和右子節點的值。

堆的實現

二叉堆通常用數組來實現

image-20221230141555180

通過數組,我們可以非常方便的找到一個節點的所有親屬。對于任意節點i,它的左孩子的索引為2i+1,右孩子的索引為2i+2,父節點的索引為(i-1)/2。例如:

  • 父節點:Math.floor((i - 1) / 2)
子節點索引父節點索引
10
31
41
52
  • 左分支節點:i * 2 + 1
父節點索引左分支節點索引
01
13
25
  • 右分支節點:i * 2 + 2
父節點索引右分支節點索引
02
14
26

react 中對最小堆的應用

在 react 中,最小堆對應的源碼在 SchedulerMinHeap.js 文件中,總共有 6 個方法,其中向外暴露了 3 個方法

  • push:向最小堆推入一個元素
  • pop:彈出一個
  • peek:取出第一個

沒有暴露的是:

  • siftUp:向上調整
  • siftDown:向下調整
  • compare:這是一個輔助方法,就是兩個元素做比較的

所謂向上調整,就是指將一個元素和它的父節點做比較,如果比父節點小,那么就應該和父節點做交換,交換完了之后繼續和上一層的父節點做比較,依此類推,直到該元素放置到了正確的位置

image-20221230142926067

向下調整,就剛好相反,元素往下走,先和左分支進行比較,如果比左分支小,那就交換。

接下來我們學習 React 最小堆算法源碼的具體實現

peek

取出堆頂的任務,堆頂一定是最小的

這個方法極其的簡單,如下:

peek(timerQueue);
export function peek(heap) {// 返回這個數組的第一個元素return heap.length === 0 ? null : heap[0];
}

push

向最小堆推入一個新任務,因為使用的是數組,所以在推入任務的時候,首先該任務是被推入到數組的最后一項,但是這個時候,涉及到一個調整,我們需要向上調整,把這個任務調整到合適的位置

push(timerQueue, newTask);
export function push(heap, node) {const index = heap.length;// 推入到數組的最后一位heap.push(node);// 向上調整,調整到合適的位置siftUp(heap, node, index);
}

pop

pop 是從任務堆里面彈出第一個任務,也就是意味著該任務已經沒有在隊列里面了

pop(taskQueue);
export function pop(heap) {if (heap.length === 0) {return null;}// 獲取數組的第一個任務(一定是最小的)const first = heap[0];// 拿到數組的最后一個const last = heap.pop();if (last !== first) {// 將最后一個任務放到第一個heap[0] = last;// 接下來向下調整siftDown(heap, last, 0);}return first;
}

具體的調整示意圖如下:

image-20221230144713347

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/13431.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/13431.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/13431.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【深入理解MySQL的索引數據結構】

文章目錄 &#x1f4d5;索引底層數據結構與算法&#x1f4d9;索引數據結構&#x1f4d8;二叉樹&#x1f4d8;紅黑樹&#x1f4d8;Hash&#x1f4d8;B-Tree&#x1f4d8;BTree &#x1f4d9;表在不同存儲引擎的存儲結構&#x1f4d8;MyISAM存儲引擎索引實現&#x1f4da;文件結構…

C語言如何創建?個動態鏈表?

一、問題 創建動態鏈表就是指在程序執?過程中&#xff0c;從?到有&#xff0c;按照需求開辟結點和輸?各結點數據&#xff0c;并建?起前后相連接的關系。那么&#xff0c;如何創建動態鏈表呢&#xff1f; 二、解答 以建??個有任意名學?數據的單向動態鏈表為例&#xff0…

使用mysql主從熱備+keepalived服務+ipvsadm工具 實現 mysql高可用主備+負載均衡

目錄 1、工作原理 2、環境準備 3、分別在主服務器和備用服務器上安裝keepalived和ipvsadm 4、修改keepalived服務的配置文件 4.1 修改主服務器上的keepalive服務的配置文件 4.2 修改備用服務器上的keepalive服務配置文件 5、編寫mysql監控腳本放到主服務器上 6、在主服…

echers配置項:X軸,Y軸顏色修改

如上圖綠框所示&#xff0c;修改x&#xff0c;y軸的顏色 let option {xAxis: {axisLine:{lineStyle:{color:red}},},yAxis: {type: value,axisLine:{lineStyle:{color:red}},}, }

學習MySQL(六):Python的連接與操作

安裝第三方模塊pymysql pip install pymysql 或者 通過PyCharm后臺操作 連接mysql # 語法示例 import pymysql db pymysql.connect(hostlocalhost,userroot,password"123456",databaseschool,port3306,charset"utf8") 數據操作的基本語法 import pymys…

通過gen_compile_commands.py產生compile_commands.json文件的方法

大家在使用vscode查看linux源代碼時&#xff0c;會有很多飄紅處&#xff0c;而且函數的跳轉非常不方便。所以linux給了一個腳本gen_compile_commands.py&#xff0c;此腳本類似ctags這樣&#xff0c;產生相應的關聯之類的數據庫&#xff0c;方便函數及文件的跳轉等等。非常好。…

軟件測試委托合同(Word原件實際參考)

一、 任務表述 二、雙方的主要義務 三、履約地點 四、合同價款 五、測試費用支付方式 六、履行的期限 七、資料的保密 八、 風險責任的承擔 九、驗收方法 十、 爭議解決 十一、 其他 十二、簽章 十三、計算機軟件產品鑒定測試保密協議 軟件資料清單列表部分文檔&#xff1a; …

Object.wait()和LockSupport.park()

Object.wait() 和 LockSupport.park() 都是用來使當前線程等待的方法&#xff0c;但它們在使用場景和機制上有所不同&#xff1a; Object.wait() 用途&#xff1a;wait() 方法屬于對象監視器&#xff08;Monitor&#xff09;的一部分&#xff0c;通常與 synchronized 塊或方法…

電感式傳感器

電感傳感器是基于電磁感應原理&#xff0c;將被測非電量&#xff08;如位移、壓力、振動等&#xff09;轉換為電感量變化的一種結構性傳感器。利用自感原理的有自感式傳感器&#xff08;可變磁阻式&#xff09;&#xff0c;利用互感原理的有互感式&#xff08;差動變壓器式和渦…

AI學習指南線性代數篇-矩陣的運算

AI學習指南線性代數篇-矩陣的運算 線性代數中&#xff0c;矩陣的運算是一項重要而基礎的內容。在人工智能領域&#xff0c;矩陣的運算被廣泛應用于各種算法中&#xff0c;如神經網絡、圖像處理、自然語言處理等。本文將從矩陣的運算概述、在AI中的使用場景、定義和意義以及公式…

QT:QML制作線形圖

目錄 一.介紹 二.引入庫 三.自定義屬性 四.懸停處理函數 五.設置X軸 六.設置Y軸 七.畫線 八.測試點坐標 九.設置值 十.效果演示 十一.代碼演示 1.LineGraph.qml 2.main.qml 一.介紹 線形圖&#xff08;也稱為折線圖&#xff09;是一種常用的數據可視化工具&#…

如何找到MySQL中存儲引擎所對應的表空間并且打開?

在上節課我們學習了數據庫&#xff08;MySQL&#xff09;進階&#xff1a;存儲引擎&#xff0c;有不少同學產生疑惑&#xff0c;到底要怎么找到表空間并且打開啊&#xff1f;這節課我們就來探討。 首先&#xff0c;根據這個路徑&#xff1a;C:\ProgramData\MySQL\MySQL Server…

mybatis-plus如何使用QueryWrapper和LambdaQueryWrapper的and方法?

構造器去構造條件的時候&#xff0c;我們都知道eq方法去鏈式的時候是自動添加and的&#xff0c;那如果需要and的那個條件需要加括號呢&#xff1f; 環境 Jdk 1.8、mybatis-plus 3.5.3.2、mysql 5.7.11 示例 sql&#xff1a; select * from user where openid 1 and (phon…

谷歌Flank潛藏3年的Github Action供應鏈攻擊

01 簡 介 Flank [1] 是谷歌 Firebase Test lab 開源在 Github 的一個項目&#xff0c;用于同時對多個安卓和IOS設備進行測試。2024年4月15號 AWS 安全工程師 Adnan Khan 公布了關于該項目代碼倉庫 Github Action CI/CD 存在漏洞的細節[2]&#xff0c;漏洞在2020年于此 代碼合…

通信網絡時鐘同步(PTP網絡授時服務器)技術探討

通信網絡時鐘同步&#xff08;NTP網絡授時服務器&#xff09;技術探討 通信網絡時鐘同步&#xff08;NTP網絡授時服務器&#xff09;技術探討 1、著移動通信業務的發展和移動用戶的快速增長&#xff0c; 移動網絡架構向IP化、寬帶化進展。為了適應業務IP化發展趨勢&#xff0c…

02 VUE學習:模板語法

模板語法 Vue 使用一種基于 HTML 的模板語法&#xff0c;使我們能夠聲明式地將其組件實例的數據綁定到呈現的 DOM 上。所有的 Vue 模板都是語法層面合法的 HTML&#xff0c;可以被符合規范的瀏覽器和 HTML 解析器解析。 在底層機制中&#xff0c;Vue 會將模板編譯成高度優化的…

開發vue3,真的可以不用ref/reactive了,也不需要ref.value

什么是Cabloy-Front&#xff1f; Cabloy-Front 是一款支持 IOC 容器的 Vue3 框架。不用ref/reactive&#xff0c;不用ref.value&#xff0c;不用pinia 與UI庫的配合 Cabloy-Front 可以搭配任何 UI 庫使用&#xff0c;并且內置了幾款 UI 庫的項目模版&#xff0c;便于開箱即用…

免費SSL證書簽發安裝指南

一、簽發 1.選擇證書頒發機構&#xff08;CA&#xff09;&#xff1a;首先&#xff0c;你需要找到一個提供免費SSL證書的CA。有些CA會提供永久免費的SSL證書&#xff0c;而有些則可能只提供有限時間的試用證書&#xff0c;如JoySSL就提供永久免費證書。 2.生成CSR&#xff08…

WPF 鼠標拖拽平移

效果 xaml <ScrollViewer x:Name"scrollViewer" HorizontalScrollBarVisibility"Hidden" VerticalScrollBarVisibility"Disabled" Background"#FFF1ADAD"PreviewMouseDown"ScrollViewer_OnPreviewMouseDown"PreviewMou…

Electron學習筆記(一)

文章目錄 相關筆記筆記說明 一、輕松入門 1、搭建開發環境2、創建窗口界面3、調試主進程 二、主進程和渲染進程1、進程互訪2、渲染進程訪問主進程類型3、渲染進程訪問主進程自定義內容4、渲染進程向主進程發送消息5、主進程向渲染進程發送消息6、多個窗口的渲染進程接收主進程發…