資料結構之線段樹剖析

2021-10-22 05:38:08 字數 2529 閱讀 1009

相關鏈結

參考對於有一類問題,我們關心的是線段(或者區間):

最經典的線段樹問題:區間染色:

操作:

另一類經典問題:區間查詢:

實質:基於區間的統計查詢,區間中的資料是會動態更新的,日常中常見的場景:

如果我們使用陣列來解決該問題,時間複雜度為:

實際需求中,我們需要效能更好的實現;

使用線段樹實現,時間複雜度為:

線段樹解決的問題:

給定的區間的長度一般是固定的;

對於乙個線段樹,每乙個節點儲存的是乙個區間中相應的統計值

統計區間中資料的和為例:

線段樹(segment tree)是一種二叉樹形資料結構,1977 年由 jon louis bentley 發明,用以儲存區間或線段,並且允許快速查詢結構內包含某一點的所有區間。

乙個包含 n 個區間的線段樹,空間複雜度為 o(n),查詢的時間複雜度則為o(logn + k),其中 k 是符合條件的區間數量。

線段樹是乙個平衡的二叉樹,所有葉子到根的距離最多隻相差1。令整個區間的長度為n,則其有n個葉節點,每個葉節點代表乙個單位區間,每個內部結點代表的區間為其兩個兒子代表區間的聯集。

線段樹不是完全二叉樹;線段樹是平衡二叉樹;堆也是平衡二叉樹。

建立線段樹:

線段樹儲存結構:

滿二叉樹的特性:

如果有n個元素的線段樹,使用陣列儲存所需的空間:

建立線段樹實現:

線段樹的查詢:

例:在以treeindex為根的線段樹中,在其區間為[l…r]的範圍裡,搜尋區間[queryl…queryr]的值,如果:

查詢區間只在右子樹,只往右子樹查詢;

查詢區間只在左子樹,只往左子樹查詢;

查詢區間部分在左子樹、部分在右子樹,分別往左、右子樹查詢,並求和

線段樹更新乙個位置:

index所在節點在右子樹,更新右子樹;

index所在節點在左子樹,更新左子樹;

更新完孩子節點,返回值後更新父節點的值;

線段樹更新乙個區間:

懶惰更新:為提高效能,採用lazy陣列記錄未更新的內容,到下次查詢區間時,查詢到具體葉子節點時,先檢查lazy陣列中是否存在未更新的葉子節點,如果存在,同新更新葉子節點;

使用線段樹:

使用陣列實現線段樹

使用二叉樹實現線段樹

線段樹區間修改使用lazy優化

leetcode 303. range sum query - immutable

leetcode 307. range sum query - mutable

segmenttree

public int getsize() 獲取線段樹元素數量

public e get(int index) 獲取線段樹某一位置的元素

public e query(int queryl, int queryr) 返回區間[queryl, queryr]的值

public void set(int index, e e) 將index位置的值,更新為e

com.chen.data.struct.segment.segmenttree1

com.chen.data.struct.segment.segmenttree2

com.chen.data.struct.segment.segmenttree3

給定乙個整數陣列 nums,求出陣列從索引 i 到 j(i ≤ j)範圍內元素的總和,包含 i、j 兩點。

實現 numarray 類:

com.chen.data.struct.segment.leetcode303numarray

給你乙個陣列 nums ,請你完成兩類查詢,其中一類查詢要求更新陣列下標對應的值,另一類查詢要求返回陣列中某個範圍內元素的總和。

實現 numarray 類:

com.chen.data.struct.segment.leetcode307numarray

wiki 百科 : 線段樹 & 線段樹 (區間查詢)

劉宇波《玩轉資料結構》課程

資料結構之線段樹

線段樹也叫區間樹,顧名思義,線段樹是一種基於區間的樹,每個節點表示乙個 線段 或 區間 樹的根節點表示是 整體 的區間,左右子樹分別表示這個區間的左半邊和右半邊。function 以節點v為根建樹 v對應區間為 l,r 線段樹的關鍵在於如何定義樹節點,以及如果構建 插入 樹節點。1.樹節點的定義 p...

資料結構之線段樹

一 引例 有m個數排成一列,做n次操作,每次操作包括 1 詢問指定區間的最大值 最小值 2 將指定區間的每個數加上乙個值 如果按照最樸素的做法,乙個個的遍歷,時間複雜度 o mn 那麼如何解決乙個區間求和 最大值,最小值 的問題呢?那麼就要用到線段樹啦。二 定義 線段樹是一種二叉搜尋樹,與區間樹相似...

資料結構之線段樹

線段樹是一種二叉查詢樹,它將乙個區間劃分為1個個單元,樹的每個節點都是1個單元。如下圖的樹就是一顆區間樹。性質 對於線段樹中的每乙個非葉子節點 a,b 它的左節點為 a,a b 2 右節點為 a b 2 1,b 線段數是平衡二叉樹,子節點的個數等於整個區間的長度。建樹 在這裡,我們使用陣列來實現簡單...