ia14
TRANSCRIPT
Augmenting Data Structure
• 基本データ構造に+αなデータを持たせることによってより多くの操作を実現する例) Dynamic Order Statistics Interval Tree
14.1 Dynamic Order Statistics
• やりたいこと: 探索木でもorder statistic(9章)を求めたい
• n個の要素のi番目のorder statistic は i番目に大きな要素のこと
• (O(n)で任意のorder statistic を求めることができた)
ノードに追加する情報
• 以下の情報をノードに追加すればorder statistic が求められる
• x.size: ノードxをルートとするサブツリーに含まれるノードの数つまり x.size = x.left.size + x.right.size + 1 (葉のsizeは1とする)
ループ不変式によるOS-Rankの正当性の確認
• 不変式: whileループ開始前にrはノードyをルートとするxのランクを示す
• ループ開始前: y = x で r = x.left.size + 1 より正しい
• ループ中: whileループの最後で y ← y.p としている.yがy.pの左の子ならy.pもy.p.right のサブツリーもxより大きいので,rはそのまま.yがy.pの右の子ならxはy.pとy.p.left のサブツリーより大きいのでその分rを増やす
• ループ終了時: y = T.root で終了.yのサブツリーとは全体の木そのもの.よってrはxのランクを表す
挿入時のsizeの更新• 赤黒木の挿入手順
1. 要素を挿入
2. バランスする用に場合によっては色を変えたり回転操作をする
• 1. のときは通過するノードのsizeを増やすだけ
• 2. のときはsizeに影響があるのは回転操作のみ.左回転のときは
挿入時のsizeの更新• 右回転時の操作は左回転のときと対称
• 1. の段階においてsizeを更新するノードはせいぜいlgNなのでそのコストはO(lgN)
• 2. の段階において,回転操作は高々2回
• よって挿入時のsize更新に伴うコストはO(lgN)
削除時のsizeの更新• sizeを変更しなければならないのは,削除するノードの親
• 親をルートまで遡って更新するが,これは O(lgN)
• また最大3回の回転が発生するものの,回転にともなうsizeの更新はO(1)でできる
• 結局削除時もO(lgN)でsizeを更新できる
データ構造を拡張するためのステップ
1. 基本となるデータ構造を決める
2. 基本データ構造に追加する情報を決める
3. その情報がデータ構造を変形するとき(挿入・削除時)でも正しく保つことができるかどうかを確認
4. 新しい操作を追加
具体例• Step1: 赤黒木を選択
• Step2: sizeフィールドを追加
• Step3: 挿入・削除時にsizeフィールドがO(lgN)でできるか確認
• Step4: OS-SelectやOS-Rankの作成
Theorem 14.1• fを赤黒木Tのn個のノードに新たに追加するフィールドだとする.ノードxについて,xのフィールドfがx,x.left,x.right のみから計算できるとき,挿入・削除に伴うfの更新はO(lgN)でおこなうこができるx.f = function(x, x.left, x.right)
証明
• 基本的な考え方は,ノードxのフィールドfを変更した場合,その変更はxの親にのみ影響するということ.x.fを変更 → x.p.fを変更 → x.p.p.fを変更→ … root.f を変更 → 終了
• 木の高さはlgNなので更新操作はO(lgN)
挿入時• 赤黒木では挿入は2つの段階からなる
• ノードxを挿入したとする
• 第一段階でx.fは定義からO(1)で計算できる.また,その後rootまでその変更は伝搬するが,それはO(lgN)
• 第二段階では回転が場合によって発生する.回転によって影響を受けるノードは2つ.第一段階同様変更はrootまで伝搬するのでO(lgN). 回転はせいぜい2回なので結局これもO(lgN)
削除時• 赤黒木では削除も二段階からなる
• ノードxを削除したとき,xが葉でなければxの子のいずれかがxの位置へ移動するが,そのときfの修正コストはO(lgN)
• 第二段階では最大3回の回転が発生するが,これもfの修正にはそれぞれO(lgN)しかかからない
14.3 Interval Tree• 赤黒木のノードがある時間区間を表すように拡張する (区間木)
• 閉区間 [t1,t2] = i とおく.このとき i.low = t1, i.high = t2 と表す.二つの区間iとi’があるとき,以下のいずれかの状況が発生する
1. iとi’はオーバラップする(重なる部分が存在する)
2. iはi’の左に位置する (i.high < i’.low)
3. iはi’の右に位置する (i’high < i.low)
Interval Tree がサポートする操作
• Interval Tree のノードxのフィールド x.int は区間を表す (x.int.low, x.int.high を持つ)
• Interval-Insert(T,x): xを挿入
• Interval-Delete(T,x): xを削除
• Interval-Search(T,i): iとオーバーラップするノードへのポインタを返す(見つからなければNIL)
データ構造を拡張するための4ステップ
• ステップ1: 基本データ構造の決定今回は赤黒木を使用.各ノードxのx.intはインターバルを表す .xの大きさはx.int.lowで表される (従って,in-orderで赤黒木を探索すると,開始時間の早いノードから取り出される)
• ステップ2: 追加する情報の決定各ノードに max というフィールドを追加する.maxはノードxをルートとするサブツリー内で最も大きい区間の終了地点 (int.high) を表す
データ構造を拡張するための4ステップ
• ステップ3: 情報の計算方法O(lgN)での計算を保障するには,maxはノードxとその子x.left,x.rightのみから計算できなければならない.実際にその3つからのみで計算できるx.max = max(x.int.high, x.left.max, x.right.max)
Theorem 14.2
• どんなInterval-Search(T,i) の呼び出しでも,Interval-Search(T,i)は必ずiとオーバラップするノードか,あるいはオーバラップするノードが無い場合はNILを返す