區間樹和線段樹

2021-06-23 07:56:03 字數 1873 閱讀 7080

注意:區間樹和線段樹不一樣哦,線段樹是一種特殊的區間樹。

區間樹

區間樹是在紅黑樹基礎上

進行擴充套件得到的支援以區間為元素的動態集合的操作,其中每個節點的關鍵值是區間的左端點。通過建立這種特定的結構,可是使區間的元素的查詢和插入都可以在o(lgn)的時間內完成。相比於基礎的紅黑樹資料結構,增加了乙個max[x],即以x為根的子樹中所有區間的斷點的最大值。邏輯結構如下所示:

區間樹具有和紅黑樹一樣的性質,並且區間樹的基礎操作和紅黑樹的基礎操作一樣。(具體紅黑樹的操作,參見

紅黑樹的性質如下:(一定要牢記哦!)

(1)節點要麼是紅色的,要麼是黑色的

(2)根節點是黑色的

(3)每個葉節點(即空節點)是黑色的

(4)若節點是紅色的,則它的孩子節點必為黑色

(5)對每個節點,從該節點到它的子孫葉子節點的所有路徑上包含相同的黑色節點。

線段樹:線段樹是一種平衡二叉查詢樹,

它將乙個區間劃分成一些單元區間,每個單元區間對應線段樹中的乙個葉結點。主要的處理思想是基於分治的思想。它的邏輯結構如下:

設根節點的區間為[a,b),區間長度為l = b - a,線段樹的性質:

(1)線段樹是乙個平衡樹,樹的高度為log(l)

(2)線段樹把區間上的任意長度為l的線段都分成不超過2log(l)線段的並

線段樹基礎儲存結構如下:(這裡使用陣列模擬指標,類似堆的儲存結構)

struct tag_linesegnode;

typedef struct tag_linesegnode lsnode;

根據線段樹的性質可知,線段樹的節點個數大於2*l,這裡設定線段樹的節點個數為lsnode node[3 * l];

線段樹的操作主要有:

(1)建立線段樹

void buildlinesegtree(int left,int right,int nodenum)

}

(2)插入線段樹

void insertlinesegtree(int left,int right,int nodenum)

if(right <= node[nodenum].mid)

else if(left >= node[nodenum].mid)

else

}

(3)查詢線段樹

int searchlinesegtree(int left,int right,int nodenum)

if(right <= node[nodenum].mid)

else if(left >= node[nodenum].mid)

else

}

(4)刪除線段樹

int deletelinesegtree(int left,int right,int nodenum)

if(right <= node[nodenum].mid)

else if(left >= node[nodenum].mid)

else

}

線段樹在一些具體的應用中,需要對輸入的資料進行離散化,以減小線段樹的大小,此時需要注意離散前和離散後的資料對應。此外,在某些應用中,需要使用lazy思想,在一些操作中先不對線段樹進行更新,而是推遲到查詢的過程中,在查詢的過程中進行更新。

線段樹(區間樹)

目錄 為什麼要使用線段樹 什麼是線段樹 線段樹融合介面 線段樹實現 線段樹例題 融合介面 author administrator param public inte ce merger package com.suanfa.segmenttree 線段樹 區間樹 author administra...

線段樹 區間樹

每乙個節點儲存的是乙個區間中相應統計值 在treeindex的位置建立表示區間 l.r 的線段樹 private void buildsegmenttree int treeindex,int l,int r int lefttreeindex leftchild treeindex int rig...

線段樹 區間合併

hdu 1540 tunnel wa re 詳細見 include include include include include define max 50010 define lson l,m,k 1 define rson m 1,r,k 1 1 using namespace std typ...