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

React Scheduler 最小堆實(shí)現(xiàn)小結(jié)

 更新時(shí)間:2026年01月27日 09:45:25   作者:_DoubleL  
本文主要介紹了React Scheduler 最小堆實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

1. 什么是最小堆

最小堆(Min Heap)是一種完全二叉樹結(jié)構(gòu),同時(shí)滿足一個(gè)很關(guān)鍵的性質(zhì):任意一個(gè)節(jié)點(diǎn)的值,都 ≤ 它的左右子節(jié)點(diǎn)的值,也就是說: ?? 堆頂(根節(jié)點(diǎn))一定是整個(gè)結(jié)構(gòu)中最小的元素

完全二叉樹的特點(diǎn)是:

  • 從上到下
  • 從左到右依次填滿
  • 只允許最后一層不滿

2. 用數(shù)組表示最小堆??

最小堆通常用數(shù)組實(shí)現(xiàn),而不是鏈表。

索引:  0  1  2  3  4  5
數(shù)組: [1, 3, 5, 4, 6, 8]

如果數(shù)組下標(biāo)從 0 開始:

  • 父節(jié)點(diǎn):(i - 1) >>> 1;
  • 左子節(jié)點(diǎn):2 * i + 1
  • 右子節(jié)點(diǎn):2 * i + 2

3. React Scheduler 最小堆實(shí)現(xiàn)

React 的 Scheduler 內(nèi)部,正是通過 最小堆 + sortIndex 來維護(hù)任務(wù)執(zhí)行順序

export type Node = {
  id: number;        // 每個(gè)任務(wù)的唯一標(biāo)識(shí)
  sortIndex: number; // 決定任務(wù)順序
};

堆的本質(zhì):數(shù)組

export type Heap<T extends Node> = Array<T>;

3.1 取出堆頂元素

export const peek = <T extends Node>(heap: Heap<T>): T | null => {
  return heap.length === 0 ? null : heap[0];
};

3.2 插入元素

插入流程:

  1. 新元素放到數(shù)組末尾
  2. 從下往上進(jìn)行 堆化(siftUp),不斷與父節(jié)點(diǎn)比較,若比父節(jié)點(diǎn)小就交換,一直向上,直到滿足堆性質(zhì)
  3. 恢復(fù)最小堆性質(zhì)

如下圖,在最后的節(jié)點(diǎn)插入1, 1和父節(jié)點(diǎn)(10)交換位置, 接著 1和父節(jié)點(diǎn)(2) 交換位置,就變成了恢復(fù)了最小堆

// 插入元素
export const push = <T extends Node>(heap: Heap<T>, node: T): void => {
  // 1. 把node放到堆的最后
  const index = heap.length;
  heap.push(node);
  // 2. 調(diào)整最小堆,從下往上堆化
  siftUp(heap, node, index);
};
?
// 從下往上堆化
export const siftUp = <T extends Node>(
  heap: Heap<T>,
  node: T,
  i: number,
): void => {
  let index = i;
?
  while (index > 0) {
    // 無符號(hào)右移,相當(dāng)于 /2 并且向下取整
    const parentIndex = (index - 1) >>> 1;
    const parent = heap[parentIndex];
    // 如果父節(jié)點(diǎn)大于node,需要交換
    if (compare(parent, node) > 0) {
      // node子節(jié)點(diǎn)更小,和根節(jié)點(diǎn)交換
      heap[parentIndex] = node;
      heap[index] = parent;
      index = parentIndex;
    } else {
      return;
    }
  }
};
?
// 比較函數(shù),返回值大于0 表示 a大于b
function compare(a: Node, b: Node) {
  const diff = a.sortIndex - b.sortIndex;
  return diff !== 0 ? diff : a.id - b.id;
}

3.3 刪除堆頂元素

刪除流程

  1. 保存堆頂元素(最小值)
  2. 取出最后一個(gè)元素
  3. 放到堆頂
  4. 從上往下堆化(siftDown),比較 node 與左右子節(jié)點(diǎn),選擇 更小的那個(gè)子節(jié)點(diǎn),若子節(jié)點(diǎn)更小,則交換,一路向下,直到恢復(fù)堆序
// 刪除堆頂元素  先取出堆頂元素,然后取出最后一個(gè)元素放到堆頂,然后從上往下堆化
export const pop = <T extends Node>(heap: Heap<T>): T | null => {
  if (!heap.length) return null;
  const first = heap[0];
  const last = heap.pop()!;
  if (first !== last) {
    // 證明heap中有2個(gè)或者更多個(gè)元素
    heap[0] = last;
    siftDown(heap, last, 0);
  }
  return first;
};

// 從上往下堆化
function siftDown<T extends Node>(heap: Heap<T>, node: T, i: number): void {
  let index = i;
  const length = heap.length;
  // 只需要取一半的節(jié)點(diǎn),因?yàn)槊看味际歉蟀脒?或者 右半邊的節(jié)點(diǎn)對(duì)比
  const halfLength = length >>> 1;
  while (index < halfLength) {
    const leftIndex = (index + 1) * 2 - 1;
    const left = heap[leftIndex];
    const rightIndex = leftIndex + 1;
    const right = heap[rightIndex]; // right不一定存在,等下還要判斷是否存在
    if (compare(left, node) < 0) {
      // left<node
      if (rightIndex < length && compare(right, left) < 0) {
        // right存在,且right<left
        heap[index] = right;
        heap[rightIndex] = node;
        index = rightIndex;
      } else {
        // left更小或者right不存在
        heap[index] = left;
        heap[leftIndex] = node;
        index = leftIndex;
      }
    } else if (rightIndex < length && compare(right, node) < 0) {
      // left>=node && right<node
      heap[index] = right;
      heap[rightIndex] = node;
      index = rightIndex;
    } else {
      // 根節(jié)點(diǎn)最小,不需要調(diào)整
      return;
    }
  }
}

// 比較函數(shù),返回值大于0 表示 a大于b
function compare(a: Node, b: Node) {
  const diff = a.sortIndex - b.sortIndex;
  return diff !== 0 ? diff : a.id - b.id;
}

到此這篇關(guān)于React Scheduler 最小堆實(shí)現(xiàn)小結(jié)的文章就介紹到這了,更多相關(guān)React Scheduler 最小堆內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • React 高階組件入門介紹

    React 高階組件入門介紹

    本篇文章主要介紹了React高階組件入門介紹,這篇文章中我們?cè)敿?xì)的介紹了什么是高階組件,如何使用高階組件,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-01-01
  • 詳解React中如何拆分組件

    詳解React中如何拆分組件

    這篇文章主要為大家詳細(xì)介紹了React中拆分組件的相關(guān)知識(shí),文中的示例代碼講解詳細(xì),對(duì)我們掌握React有一定的幫助,需要的小伙伴可以參考一下
    2023-12-12
  • react?hooks?計(jì)數(shù)器實(shí)現(xiàn)代碼

    react?hooks?計(jì)數(shù)器實(shí)現(xiàn)代碼

    這篇文章主要介紹了react?hooks計(jì)數(shù)器實(shí)現(xiàn)代碼,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-08-08
  • react源碼層探究setState作用

    react源碼層探究setState作用

    寫react的時(shí)候,踩了幾次坑發(fā)現(xiàn)setstate之后state不會(huì)立刻更新,于是判定setstate就是異步的方法,但是直到有一天,我想立刻拿到更新的state去傳參另一個(gè)方法的時(shí)候,才問自己,為什么setstate是異步的?準(zhǔn)確地說,在React內(nèi)部機(jī)制能檢測(cè)到的地方,setState就是異步的
    2022-10-10
  • React掌握openapi-typescript-codegen快速生成API客戶端代碼的過程

    React掌握openapi-typescript-codegen快速生成API客戶端代碼的過程

    openapi-typescript-codegen是一個(gè)開源工具,用于根據(jù)OpenAPI規(guī)范自動(dòng)生成TypeScript代碼,包括類型定義和API客戶端代碼,它幫助開發(fā)者節(jié)省手動(dòng)編寫代碼的時(shí)間,提高開發(fā)效率,感興趣的朋友一起看看吧
    2024-11-11
  • React Context跨層級(jí)通信的利器

    React Context跨層級(jí)通信的利器

    本文主要介紹了React Context跨層級(jí)通信的利器,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2026-05-05
  • React+Antd修改Table組件滾動(dòng)條樣式的操作代碼

    React+Antd修改Table組件滾動(dòng)條樣式的操作代碼

    這篇文章主要介紹了React+Antd修改Table組件滾動(dòng)條樣式的操作代碼,本文給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧
    2024-12-12
  • React獲取setState更新后值的多種方案

    React獲取setState更新后值的多種方案

    在React開發(fā)中,很多新手都會(huì)遇到一個(gè)常見坑:調(diào)用setState更新狀態(tài)后,立即讀取狀態(tài)卻拿到舊值,本文將從問題本質(zhì)出發(fā),分類詳解類組件和函數(shù)組件中獲取setState更新后值的多種方案,需要的朋友可以參考下
    2025-12-12
  • React閉包陷阱產(chǎn)生和解決小結(jié)

    React閉包陷阱產(chǎn)生和解決小結(jié)

    閉包陷阱是一個(gè)常見的問題,尤其是在處理異步操作、事件處理器、或是定時(shí)器時(shí),本文就來介紹一下React閉包陷阱產(chǎn)生和解決小結(jié),具有一定的參考價(jià)值,感興趣的可以了解一下
    2025-04-04
  • ReactNative列表ListView的用法

    ReactNative列表ListView的用法

    本篇文章主要介紹了ReactNative列表ListView的用法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-08-08

最新評(píng)論

南和县| 乌恰县| 普陀区| 上杭县| 灵璧县| 兴化市| 洛浦县| 青神县| 公主岭市| 古丈县| 衡南县| 兖州市| 南昌县| 那曲县| 佳木斯市| 通州区| 济阳县| 南昌县| 九江市| 六安市| 古丈县| 桃江县| 上饶县| 平南县| 望江县| 勐海县| 新乐市| 谢通门县| 三门县| 江阴市| 青州市| 宜阳县| 洞头县| 化州市| 巨野县| 郎溪县| 灵武市| 靖州| 沧源| 房山区| 田阳县|