永続性(FHQ treap)バランスの取れたツリーをすることができ

抜粋:https://www.cnblogs.com/mjtcn/p/8028926.html%グレート神 

テキスト

FHQ treap仕上げ

 

treap =ツリー+ヒープ、すなわち、特性を満足しながら、二分探索木とヒープ。

木の両側極力ので、彼は木のバランスを維持するために、積み重ね自然を満たすように、キーの値があるバランスの大きさは、キー値がランダムであることを確実にするために。

 

treapバランスの取れたツリーは、前駆体の一般的な機能、後継者を持って、k番目のランク付け、最大のクエリ、挿入、削除。また、より良い書き込みするの

しかし、問題の間隔は、たとえば、実行することはできません、

  • 間隔を短く
  • インターバル最も値
  • 間隔反転(リバース)
  • 可動部(セクションカットアンドペースト)

(行うことができますスプレイ)

-しかし、魔法のデータ構造が存在する、すなわち、treap機能も間隔で動作することができる満たすFHQ treap

 

コードの量もはるかに小さいのでFHQは、2つだけの基本的な操作をtreap。

スプリット

二つに分離treapのtreapを話します。

分離の2つのタイプが1より大きい、以下Kに、重量ヴァルポイントに応じて、存在しています。もう一つは、除去前部分にkの数です。

重量:

分割ツリーを再構築するときにそのようTreapため、以下、K点は、サブツリー内に存在するが、kのZhekeサブツリーより大きい有していてもよいです。

 

コードをコピー
(今INT、int型K、INT&X、INT&Y)1つの空隙分割{ 
 2であればX = Y = 0(今!)。
 3そう{ 
 4もし(ヴァル[今] <= K)
 5×=今、スプリット(CH [今] [1]、K、CH [今] [1]、Y)。
 他の6 
 7 Y =今、スプリット(CH [今] [0]、K、X、CH [今] [0])。
 8押し上げ(今)。
 9} 
10}
コードをコピー

コードは、それは、2つの値、X、Yを指し、非常に素晴らしいです、これら2つの値は、二つの変数の復興の中で最も重要であり、アドレスの文字を取らなければなりません。

xは基準ノードK以下(仮定)、右の息子は、yは基準ノードが息子kを放置するよりも大きいです。

kは以下であり、その左部分木は、右の子k個以下であるが、必ずしもkより小さくない場合、ので、ここでそれが適切な息子を取られ、第一のノードに遭遇したときはK未満です、それは右の息子であるとします。

図は、右の子が適切な息子が変化するように、次の工程は、右子を左に行くために、6よりも大きいことが見出され、K = 6、その後、6未満であり、右に移動し、次6の重量にポイント。

復興プロセス:値は、彼はいくつかは、k個未満の左、右のように行っていた今現在のポイントkよりも小さい場合。

複雑さ  O L O GのN- O(logN個)

 

フロントセクション番号k

 

コードをコピー
(今INT、int型K、INT&X、INT&Y)1つの空隙分割{ 
 2であればX = Y = 0(今!)。
 他の3 { 
 4もし(K <= SIZ [CH [今] [0]]) 
 5 Y =今、スプリット(CH [今] [0]、K、X、CH [今] [0])。
 他の6 
 7 X =今、スプリット(CH [今] [1]、K-SIZ [CH [今] [0]] - 1、CH [今] [1]、Y)。
 8押し上げ(今)。
 9} 
10}
コードをコピー

 

 

原理は詳細に説明されていない、同じです。

複雑、O L O GのN- O(logN個)

 

マージ

すべてのツリーノードの重みの全ての点が第サブツリーの粒子よりも小さいことを保証する合成二サブツリー。

そして、十分なヒープの性質限り、再構築します。

2変数x、yがあり、

 

コードをコピー
1つのINTマージ(int型のx、int型のY){ 
 2であればリターンX + Y(X || Y!)。
 3 IF(キー[X] <キー[Y]){ 
 4個のCH [X] [1] =マージ(CH [X] [1]、Y)。
 5押し上げ(X)。Xを返します。    
 6} 
 そう7 { 
 8 CH [Y] [0] =マージ(X、CH [Y] [0])。
 9押し上げ(Y)。Yを返します。
10} 
11}
コードをコピー

 

ここでは、xツリーキー時間は、xの左半分のみがツリーの復興に添加した場合に、yのサブツリー時間は、それが唯一のサブツリーの右半分に追加ことがわかります。自然のtreapを満たすために。

 

複雑さ  O L O GのN- O(logN個)

 

二つの基本的な操作は完了です。

 

インサート

重み値kの数を挿入します。

プロセス:未満またはKに等しい2つにtreap、kはXよりも大きいと、2つのサブツリーを組み合わせることができます

 

スプリット(ルート、K、X、Y)。
ルート=併合(マージ(X、MAKENODE(k))を、Y);

 

削除

数kの値を削除する権利。

プロセス:最初未満またはKより大きい等しいk個に分割し、B、次いでK-1にxまたは以下CとDは、K-1よりも大きい場合、kはDであり、それは二人の息子dをマージし、次いでC、Bを組み合わせることができます。

 

スプリット(ルート、X、Y)
スプリット(X-1、X、Z)。
Z =マージ(CH [I] [0]、B [i]を[1])。
ルート=併合(マージ(X、Z)、S);

 

Kランキング

Kは、ランキングを求めています

手順:K-1 X以下に等しく、K-1、Y 2つのサブツリーを超えるに、xはランクkのサブツリーの大きさです。

 

スプリット(ルート、K-1、x、y)は、
printf( "%d個の\ n"、SIZ [X] +1)。
ルート=(x、y)をマージします。

 

最初の数k

kの数を求めて

プロセス:決意とスプレイ、treap等。

コードをコピー
インラインINT getkth(INT P、INT K){ 
    一方(TRUE){ 
        IF(K == SIZ [CH [P] [0] + 1)リターンP。
        IF(CH [P] [0] && K <= SIZ [CH [P] [0]])P = CH [P] [0]。
        他K- =(?(CH [P] [0] SIZ [CH [P] [0]:0)+ 1)、P = CH [P] [1]。
    } 
}
コードをコピー

 

前駆

Kは、ランキングを求めています

手順:K-1 X以下に等しく、K-1、Y 2つのサブツリーを超えるに、Xサブツリーは、最大数x前駆体です。

スプリット(ルート、K-1、x、y)は、
printf( "%d個の\ n"、ヴァル[getkth(X、SIZ [X])])。
ルート=(x、y)をマージします。

 

後継者

Kは、ランキングを求めています

プロセス:Xに少ないK、およびy kは2つのサブツリーのサブツリーY xは前駆体の最小数よりも大きいです。

スプリット(ルート、K、X、Y)。
printf( "%d個の\ n"、ヴァル[getkth(Y、1)])。
ルート=(x、y)をマージします。

 

基本的な操作は、これらがFHQtreapであるということです

おすすめ

転載: www.cnblogs.com/ZJXXCN/p/11455088.html