色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

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

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

3天內不再提示

一個數據結構-線段樹

算法與數據結構 ? 來源:算法與數據結構 ? 2020-05-06 11:02 ? 次閱讀

一、概念解析

這次來介紹一個數據結構 - 線段樹。

在平時刷題或是工作中,經常會遇到這么一個問題,“給定一個數組,求出數組某段區間的一些性質”。

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

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

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

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

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

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

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

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

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

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

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

情況一:節點區間包含查找區間。這種情況直接遞歸向下查找即可

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

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

情況四:節點區間相等于查找區間。直接返回答案

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

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

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

二、動畫描述

三、代碼實現

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){ //如果節點區間相等于查找區間,直接返回對應的值即可 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)?{ ????????????//?節點相交查找區間的情況 ????????????if?(end?>mid){ leftMax=query(root.left,start,mid); }//節點包含查找區間的情況 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 個節點,你可能會問這個 2n 是怎么得到的,思考這個問題可以從葉子節點出發,一共有 n 個葉子節點,構建操作是從上往下不斷二分,這樣保證了樹的平衡,因此所有節點個數就是 n + n/2 + n/4 + ... + 1 = 2n。

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

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

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 數據結構
    +關注

    關注

    3

    文章

    573

    瀏覽量

    40187
  • 二叉樹
    +關注

    關注

    0

    文章

    74

    瀏覽量

    12360
  • 數組
    +關注

    關注

    1

    文章

    417

    瀏覽量

    25997

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

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

收藏 人收藏

    評論

    相關推薦

    如何把兩個數據返回給調用函數

    函數的處理結果包含兩個數據,如何把兩個數據返回給調用函數? 第種,把兩個數據封裝成
    的頭像 發表于 01-08 10:15 ?84次閱讀

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

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

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

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

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

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

    視覺軟件HALCON的數據結構

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

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

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

    嵌入式常用數據結構有哪些

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

    20個數據可以訓練神經網絡嗎

    當然可以,20個數據點對于訓練神經網絡來說可能非常有限,但這并不意味著它們不能用于訓練。實際上,神經網絡可以訓練在非常小的數據集上,但需要采取
    的頭像 發表于 07-11 10:29 ?1053次閱讀

    原理圖設計里兩顆重要的(國產EDA)

    原理圖里面兩顆重要的,那就是元件和網絡,作為EDA工具中的重要視圖和概念,雖然看似枯燥,但它們扮演著非常重要的角色,它們為電路圖的層次化結構提供了有力支撐。想象
    的頭像 發表于 05-29 17:47 ?793次閱讀
    原理圖設計里兩顆重要的<b class='flag-5'>樹</b>(國產EDA)

    STM32F0xx_HAL_Driver庫的串口接收數據個數,是不是只能寫成1,一個一個數據接收?

    ,uint8_t *pData, uint16_tSize, uint32_tTimeout ) 函數的第三參數是接收數據個數。 問題是: 如果不知道接收數據
    發表于 05-14 06:39

    STM32F429如何次傳3000個數據

    正點原子的歷程中實用的是8位的數據傳輸,也就是說最多次能傳255個數據,我要是次想傳3000個數據,應該怎么更給程序?
    發表于 05-11 08:56

    揭秘編程核心:基本數據結構與算法思想詳解

    描述問題的數據除了各數據元素本身,還要考慮各元素的邏輯關系,主要是一對一的線性關系,對多的型關系和多對多的圖形關系。
    的頭像 發表于 04-25 11:51 ?1134次閱讀
    揭秘編程核心:基本<b class='flag-5'>數據結構</b>與算法思想詳解

    探索編程世界的七大數據結構

    結構就像是顆倒掛的小樹,有根、有枝、有葉。它是種非線性的數據結構,以層級的方式存儲數據,頂部是根節點,底部是葉節點。
    的頭像 發表于 04-16 12:04 ?419次閱讀

    TASKING編譯器是否可以將數據結構設置為 \"打包\"?

    TASKING 編譯器是否可以將數據結構設置為 \"打包\"? GCC 很早以前就提供了這種可能性,可以將__attribute__((packed))與對齊指令結合使用。 對于
    發表于 03-05 06:00

    矢量與柵格數據結構各有什么特征

    數據結構是使用點、線和面等基本幾何圖形來描述和表示地理對象的種方法。它們由離散的幾何對象和與之相關的屬性數據組成。矢量數據中的點表示
    的頭像 發表于 02-25 15:06 ?2735次閱讀
    主站蜘蛛池模板: 99在线免费| 特大黑人娇小亚洲女mp4| chinesevideoshd性舞| 色欲av蜜臀av高清| 久久精品国产午夜伦班片| 啊好深啊别拔就射在里面| 午夜天堂AV久久久噜噜噜| 免费精品国产人妻国语| 国产毛片视频网站| 57PAO强力打造高清免费| 亚洲精品国产拍在线观看| 日日夜夜撸 在线影院| 暖暖视频大全免费观看| 久久久精品久久| 国产亚洲综合视频| 国产东北男同志videos网站| www.青青草原| 99re5久久热在线| 伊人青青操| 亚洲精品综合在线影院| 午夜国产在线观看| 色狠狠色狠狠综合天天| 欧美午夜不卡在线观看| 麻豆一区二区三区蜜桃免费| 精品福利一区| 含羞草影院AE在线观看| 国产人A片在线乱码视频| 冈本视频黄页正版| writeas雷狮直播| 6080yy亚洲久久无码| 伊人无码高清| 一个人在线观看免费高清视频在线观看 | 乱子伦在线观看中文字幕| 精品无码久久久久久动漫| 国产在线高清视频无码| 国产精品久久久久久久久久免费| 欧美乱妇狂野欧美在线视频| 理论片87福利理论电影| 狼群资源网中文字幕| 老师真棒无遮瑕版漫画免费| 九九久久久|