一区二区三区三上|欧美在线视频五区|国产午夜无码在线观看视频|亚洲国产裸体网站|无码成年人影视|亚洲AV亚洲AV|成人开心激情五月|欧美性爱内射视频|超碰人人干人人上|一区二区无码三区亚洲人区久久精品

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內(nèi)不再提示

一個數(shù)據(jù)結構-線段樹

算法與數(shù)據(jù)結構 ? 來源:算法與數(shù)據(jù)結構 ? 2020-05-06 11:02 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

一、概念解析

這次來介紹一個數(shù)據(jù)結構 - 線段樹。

在平時刷題或是工作中,經(jīng)常會遇到這么一個問題,“給定一個數(shù)組,求出數(shù)組某段區(qū)間的一些性質(zhì)”。

比如給定一個數(shù)組 [5,2,6,1,-4,0,9,2],讓你求出區(qū)間 [1,4] 上所有元素的和,在這個例子中,答案是 2 + 6 + 1 + (-4) = 5。

你可能會說,直接遍歷一遍不就好了嗎?

最簡單的方式就是直接遍歷一遍區(qū)間,時間復雜度也顯而易見 O(n),如果在這個數(shù)組上頻繁進行這個操作,那么效率相對來說會比較低,怎么優(yōu)化呢?

對于求區(qū)間和的問題,前綴和數(shù)組是一個不錯的選擇,構建好前綴和數(shù)組后,求一個區(qū)間和的話只要前后一減就可以了,如果不算構建數(shù)組的時間,那么每次的操作時間復雜度就是 O(1)。

這里的問題在于前綴和數(shù)組只能解決求區(qū)間和的問題,但是其他的區(qū)間問題,前綴和數(shù)組并不能很好的解決,比如求某段區(qū)間上的最大值。

因此我們需要一個數(shù)據(jù)結構能夠幫助我們解決大部分數(shù)組的區(qū)間問題,而且時間復雜度要盡可能的低。

這也就是今天的主題 - 線段樹,首先要說明一點的是,線段樹也是二叉樹,只是它的節(jié)點里面含有區(qū)間的信息。

線段樹每個節(jié)點表示的是一個區(qū)間,每個節(jié)點將其表示的區(qū)間一分為二,左邊分到左子樹,右邊分到右子樹,根節(jié)點表示的是整個區(qū)間(也就是整個數(shù)組),葉子節(jié)點表示的是一個 index(也就是單個元素),因為每次對半分的緣故,線段樹構建出來是平衡的,也就是說樹的高度是 O(logn),這里的 n 表示的是數(shù)組中所有的元素,這一點對于我們后面分析復雜度很重要。

線段樹有三個基本的操作,分別是構建線段樹(build)、區(qū)間查找(query)、還有就是修改(modify),假設我們現(xiàn)在需要解決的問題是 “求區(qū)間上的最大值”,例子還是之前的例子,一起來看看怎么實現(xiàn)這些操作。

對于構建操作來說,相對簡單,你只需要記住 “自上而下而下遞歸分裂,自下而上回溯更新” 從根節(jié)點到葉子節(jié)點我們不斷地將區(qū)間一分為二,從葉子節(jié)點開始返回值,一直到根節(jié)點,不斷地更新區(qū)間信息。

查找操作是線段樹的核心操作,考慮的情況相對較多,這里有四種情況:

情況一:節(jié)點區(qū)間包含查找區(qū)間。這種情況直接遞歸向下查找即可

情況二:節(jié)點區(qū)間不相交于查找區(qū)間。因為沒有要查找的范圍,停止搜索

情況三:節(jié)點區(qū)間相交但不包含查找區(qū)間。將區(qū)間分成兩段,分別查找

情況四:節(jié)點區(qū)間相等于查找區(qū)間。直接返回答案

說明一下,這里說的 “包含” 的意思是一個區(qū)間全部元素都被另外一個區(qū)間涵蓋,“相交” 的意思是一個區(qū)間的部分元素被另外一個區(qū)間涵蓋,例如要查找的區(qū)間是 [1,3],那么 [0,4] 包含要查找的區(qū)間,[2,5] 只是相交要查找的區(qū)間。對于區(qū)間查找,后面有圖解,跟著例子走一遍印象會更深刻。

最后一個修改操作,和構建操作類似,但有些許不同,你只需要記住 “自上而下遞歸查找,自下而上回溯更新”。修改的意思是,修改數(shù)組中的一個元素的值,這會影響相關的區(qū)間,相關的樹節(jié)點,因此,相關聯(lián)的節(jié)點也就需要更新。

線段樹靈活的地方在于,樹節(jié)點中存放的數(shù)據(jù)不同,它的功能就不同,比如說,你想要求解區(qū)間和,那么樹節(jié)點中就存放對應區(qū)間元素的和,你想求解區(qū)間上的最大值,那么樹節(jié)點中存放的就是對應區(qū)間上的最大值。不過話說回來,線段樹并不是一個被廣泛應用的數(shù)據(jù)結構,原因可能在于線段樹的構建和使用相對于前綴和數(shù)組這樣的技巧來說,稍微復雜了些。但是在解決數(shù)組區(qū)間的問題上,線段樹可以提供一個還不錯的思考方向。

二、動畫描述

三、代碼實現(xiàn)

publicclassSolution{ privateclassSegmentTreeNode{ intstart,end,max; SegmentTreeNodeleft,right; SegmentTreeNode(intstart,intend,intmax){ this.start=start; this.end=end; this.max=max; this.left=this.right=null; } } publicSegmentTreeNodebuild(intstart,intend,int[]nums){ if(start>end){ returnnull; } if(start==end){ returnnewSegmentTreeNode(start,end,nums[start]); } SegmentTreeNodenode=newSegmentTreeNode(start,end,nums[start]); //自上而下而下遞歸分裂 if(start!=end){ intmid=(start+end)/2; node.left=build(start,mid,nums); node.right=build(mid+1,end,nums); } //自下而上回溯更新 if(node.left!=null&&node.left.max>node.max){ node.max=node.left.max; } if(node.right!=null&&node.right.max>node.max){ node.max=node.right.max; } returnnode.max; } publicintquery(SegmentTreeNoderoot,intstart,intend){ //如果節(jié)點區(qū)間相等于查找區(qū)間,直接返回對應的值即可 if(root.start==start&&root.end==end){ returnroot.max; } intmid=(root.start+root.end)/2; intleftMax=Integer.MIN_VALUE,rightMax=Integer.MIN_VALUE; //判斷是否需要去左子樹查找 if(start<=?mid)?{ ????????????//?節(jié)點相交查找區(qū)間的情況 ????????????if?(end?>mid){ leftMax=query(root.left,start,mid); }//節(jié)點包含查找區(qū)間的情況 else{ leftMax=query(root.left,start,end); } } //判斷是否需要去右子樹查找 if(mid=root.end){ return; } //自上而下遞歸查找 modify(root.left,index,value); modify(root.right,index,value); //自下而上回溯更新 root.max=Math.max(root.left.max,root.right.max); } }

四、復雜度分析

三個操作中,構建樹的操作的時間復雜度是 O(n),原因也很好解釋,構建的樹有 2n 個節(jié)點,你可能會問這個 2n 是怎么得到的,思考這個問題可以從葉子節(jié)點出發(fā),一共有 n 個葉子節(jié)點,構建操作是從上往下不斷二分,這樣保證了樹的平衡,因此所有節(jié)點個數(shù)就是 n + n/2 + n/4 + ... + 1 = 2n。

由于構建每個節(jié)點只花了 O(1) 的時間,因此整個構建的時間復雜度就是 O(2n),忽略常數(shù)項,也就是 O(n)。

修改和查找都是沿著一條或者幾條從上到下的路徑進行的,因為樹的高度是 O(logn),所以這兩個操作的時間復雜度也是 O(logn)??梢钥吹竭@個時間復雜度比暴力的 O(n) 還是快不少。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內(nèi)容侵權或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 數(shù)據(jù)結構

    關注

    3

    文章

    573

    瀏覽量

    40741
  • 二叉樹
    +關注

    關注

    0

    文章

    74

    瀏覽量

    12636
  • 數(shù)組
    +關注

    關注

    1

    文章

    420

    瀏覽量

    26539

原文標題:什么是線段樹?

文章出處:【微信號:TheAlgorithm,微信公眾號:算法與數(shù)據(jù)結構】歡迎添加關注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關推薦
    熱點推薦

    程序設計與數(shù)據(jù)結構

    《程序設計與數(shù)據(jù)結構》重點闡述了三大方向內(nèi)容: 1. C語言學習中的痛點:針對當前工程師在C語言學習中的痛點,如指針函數(shù)與函數(shù)指針,如何靈活應用結構體等。從變量的三要素(變量的類型,變量的值和變量
    發(fā)表于 05-13 16:45

    STM32H747I DSI模塊采用個數(shù)據(jù)通道無法顯示圖片怎么解決?

    在官方例程LCD_DSI_CmdMode_SingleBuffer中DSI采用的兩個數(shù)據(jù)通道與顯示屏通信,顯示屏可以正確顯示?,F(xiàn)在我希望采用個數(shù)據(jù)通道與顯示屏通信,于是我就在官方例程中做了
    發(fā)表于 03-07 08:11

    科技在物聯(lián)網(wǎng)方面

    科技在物聯(lián)網(wǎng)領域有多方面的涉及和發(fā)展,以下是些具體信息: 傳感器技術合作 與傳感器公司合作:宇科技與些傳感器技術公司有合作,例如奧比中光為宇
    發(fā)表于 02-04 06:48

    DAC8728多通道輸出數(shù)據(jù),不能保持上一個數(shù)據(jù)嗎?

    比如我給0通道寫數(shù)據(jù)的時候,此時其他通道是置零的嗎?不能保持上一個數(shù)據(jù)嗎? 現(xiàn)在多通道輸出的正弦波都是這個樣子的,請問是不是我分析的這個原因呢?
    發(fā)表于 01-13 07:07

    如何把兩個數(shù)據(jù)返回給調(diào)用函數(shù)

    函數(shù)的處理結果包含兩個數(shù)據(jù),如何把兩個數(shù)據(jù)返回給調(diào)用函數(shù)? 第種,把兩個數(shù)據(jù)封裝成
    的頭像 發(fā)表于 01-08 10:15 ?407次閱讀

    嵌入式學習-飛凌嵌入式ElfBoard ELF 1板卡-初識設備之設備組成和結構

    項技能。設備的起源設備(Device Tree)是種描述硬件資源的數(shù)據(jù)結構,它由uboot傳遞給Linux內(nèi)核,被內(nèi)核解析,內(nèi)核根
    發(fā)表于 01-08 08:32

    飛凌嵌入式ElfBoard ELF 1板卡-初識設備之設備組成和結構

    項技能。設備的起源設備(Device Tree)是種描述硬件資源的數(shù)據(jù)結構,它由uboot傳遞給Linux內(nèi)核,被內(nèi)核解析,內(nèi)核根
    發(fā)表于 01-07 09:16

    用ADS1256結合飛思卡爾的單片機設計個數(shù)據(jù)采集系統(tǒng),為什么采用SPI通信時得到的總是固定的數(shù)?

    我準備用ADS1256結合飛思卡爾的單片機設計個數(shù)據(jù)采集系統(tǒng),但是不知道為什么采用SPI通信時,得到的總是固定的數(shù)。
    發(fā)表于 01-02 06:02

    DDC264配置寄存器數(shù)據(jù)寫入和320 DCLK時鐘脈沖后的回讀數(shù)據(jù)結構是什么?

    配置寄存器數(shù)據(jù)寫入和320 DCLK時鐘脈沖后的回讀數(shù)據(jù)結構是什么? 根據(jù)注和表9,16位配置寄存器數(shù)據(jù),4位修訂ID, 300位校驗模式,怎么可能有1024 TOTAL READBACK BITS, format = 0
    發(fā)表于 11-19 07:58

    視覺軟件HALCON的數(shù)據(jù)結構

    在研究機器視覺算法之前,我們需要先了解機器視覺應用中涉及的基本數(shù)據(jù)結構。Halcon數(shù)據(jù)結構主要有圖像參數(shù)和控制參數(shù)兩類參數(shù)。圖像參數(shù)包括:image、region、XLD,控制參數(shù)包括:string、integer、real、handle、tuple數(shù)組等。
    的頭像 發(fā)表于 11-14 10:20 ?1283次閱讀
    視覺軟件HALCON的<b class='flag-5'>數(shù)據(jù)結構</b>

    何為Teable多維表格數(shù)據(jù)庫,它僅僅是在線的智能表格嗎?

    維表格是種創(chuàng)新的數(shù)據(jù)管理和協(xié)作工具,它結合了傳統(tǒng)電子表格的直觀界面與關系數(shù)據(jù)庫的強大功能。用戶不僅可以像在Excel中樣在二維表格內(nèi)記錄和編輯數(shù)
    的頭像 發(fā)表于 10-14 16:13 ?1335次閱讀

    什么是默克爾(Merkle Tree)?如何計算默克爾根?

    01 默克爾的概念 默克爾(Merkle Tree)是種特殊的二叉,它的每個節(jié)點都存儲了個數(shù)據(jù)
    的頭像 發(fā)表于 09-30 18:22 ?2313次閱讀
    什么是默克爾<b class='flag-5'>樹</b>(Merkle Tree)?如何計算默克爾根?

    使用ISO124做一個數(shù)據(jù)采集系統(tǒng),如何減小ISO124的失調(diào)電壓的影響?

    我在使用ISO124做一個數(shù)據(jù)采集系統(tǒng),由于ISO本身的失調(diào)電壓為20mV左右,對采樣精度的影響比較大,請問有沒有什么方法可以減小失調(diào)電壓的影響?謝謝
    發(fā)表于 09-25 06:03

    嵌入式常用數(shù)據(jù)結構有哪些

    在嵌入式編程中,數(shù)據(jù)結構的選擇和使用對于程序的性能、內(nèi)存管理以及開發(fā)效率都具有重要影響。嵌入式系統(tǒng)由于資源受限(如處理器速度、內(nèi)存大小等),因此對數(shù)據(jù)結構的選擇和使用尤為關鍵。以下是嵌入式編程中常用的幾種數(shù)據(jù)結構,結合具體特點和
    的頭像 發(fā)表于 09-02 15:25 ?1038次閱讀

    plc有三個數(shù)據(jù),在網(wǎng)關中如何整合成呢?

    如:plc有三個數(shù)據(jù),在網(wǎng)關中如何整合成呢? 加注泵狀態(tài):正在加注PLC MM1.6離散量R/W 加注泵狀態(tài):未加注PLC MM1.7離散量R/W 加注泵狀態(tài):故障PLC MM2.0離散量R/W
    發(fā)表于 07-24 07:46