エントリー
こんにちは、habravchane。 これは、SMASデータ構造を共有したい最初の投稿です。 記事の最後に、提案されたデータ構造のクラスであるC ++が提供されます。 実装は再帰的ですが、私の目標はアイデアを伝えることです。 2番目は、非再帰バージョンの実装です。 意見を「聞く」ことが重要です。
ツリーの何が問題になっていますか?
はい、
なぜ配列をソートしないのですか?
ソートされた配列のバイナリ検索は、バイナリ検索ツリーと同じ対数複雑度で実装されますが、バイナリ検索ツリーのように、リンクをより小さなサブツリーにドラッグする必要はありません。
しかし、ソートされた配列の何が問題になっていますか?
はい、すべてがそうです、新しい要素を追加する(古い要素を削除する)場合、配列は次のように言うので、そのような配列に要素を追加または削除する必要がない場合にのみ
しかし、理想的なケースがあります-新しい要素が他の要素よりも大きく、単に最後に追加するだけで十分な場合。 これは理想的です-たった1つの操作ですが、そのような理想的なケースの確率論的評価により、バイナリツリーやハッシュテーブル、または他の非常に美しく独創的なメカニズムを使用せざるを得ません。 確率理論に基づいて、この状況はまれです-すべての要素が昇順で配列に追加される場合のみです(ソートされた入力データが線形複雑性を持つリンクリストに縮退する最悪のケースである場合、バイナリ検索ツリーでの皮肉アナロジー)。
特別な場合、パターンはどうですか?
しかし、1つの要素のみの配列を見てみましょう。 どの値を入力してもかまいません。常にその前の空の配列の先頭に収まり、1要素配列はもちろん常にソートされます。 また、2番目の要素をデータ構造に合わせたい場合はどうでしょうか? 別の1要素配列を作成し、2つのソートされた1要素配列を取得してみましょう。 2つの並べ替えられた配列から新しい並べ替えられた配列を取得するのは非常に高速ではありませんが、単純なタスクです...しかし、この場合、挿入するたびにではなく、2番目の挿入ごとに配列を並べ替える必要があります。 遅延ソートを使用します。
そして、3つ以上の要素を追加したい場合は? 欲しいの
負荷分散
このアルゴリズムは、通常の配列のソートに比べて、ソートの数をすでに大幅に削減していることは明らかです。なぜなら、配列の最初のレベルは1回、2番目のレベル-4番目の挿入ごと、3番目のレベル-8番目の挿入ごとにソートする必要があるからです。対数の複雑さ。
これを鎮めることはできますが
検索する
検索は、ソートされた配列に対する古典的なバイナリ検索です。唯一の違いは、配列が多数あり、それらすべてを順番に検索する必要があることです。 そのため、検索の対数計算の複雑さが議論されています(間違えなければ、これは対数計算の2倍になります)。 しかし、手元のタスクでは、メモリが節約されていることを考えると、これはまったく問題ありません。
実装
やかんが沸騰している間、私はまだ書きたいと思っていましたが、やかんが沸騰し始め、そのwhiが私が再び書きたいことを忘れさせました...
私の頭にはこの車全体がどのように行くのかという表面的なアイデアしかなかったので、実装は非常に混乱していました-コードはほぼランダムに書かれていた
実際にコード
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <windows.h> #define undefined 2147483648 class ARRAY { private: ARRAY*nextLevel; unsigned int *keyResult, // - keyLeft, keyRight *keyLeft, // *keyRight, // *keyTemp, // *valResult, // , *valLeft, // *valRight, // *valTemp, // countResult,countLeft,countRight, // 1 2 0 . len;// ( 0- 2 ) void upd() // { if(keyResult) { if(countLeft<len) { if(countRight<len) { if(keyLeft[countLeft]<keyRight[countRight])// 1- 2- - { keyResult[countResult]=keyLeft[countLeft]; valResult[countResult]=valLeft[countLeft]; countResult++; countLeft++; } else// 2- 1- - { keyResult[countResult]=keyRight[countRight]; valResult[countResult]=valRight[countRight]; countResult++; countRight++; } } else // 2- . { keyResult[countResult]=keyLeft[countLeft]; valResult[countResult]=valLeft[countLeft]; countResult++; countLeft++; } } else { if(countRight<len) // 1- - . { keyResult[countResult]=keyRight[countRight]; valResult[countResult]=valRight[countRight]; countResult++; countRight++; } // - } if(countResult==len*2) // { if(!nextLevel)nextLevel=new ARRAY; // . , nextLevel->set(keyResult,valResult,len*2); keyResult=NULL; keyLeft=NULL; keyRight=NULL; keyTemp=NULL; valResult=NULL; valLeft=NULL; valRight=NULL; valTemp=NULL; } } if(nextLevel)nextLevel->upd(); } void set(unsigned int*Key,unsigned int*Val,unsigned int Len) { len=Len; if(!keyTemp){keyTemp=Key;valTemp=Val;} else { keyLeft=Key; valLeft=Val; keyRight=keyTemp; valRight=valTemp; keyTemp=NULL; valTemp=NULL; countResult=0; countLeft=0; countRight=0; keyResult=new unsigned int[len*2]; valResult=new unsigned int[len*2]; } upd(); } public: ~ARRAY() { if(keyResult)delete[]keyResult; if(keyLeft)delete[]keyLeft; if(keyRight)delete[]keyRight; if(keyTemp)delete[]keyTemp; if(valResult)delete[]valResult; if(valLeft)delete[]valLeft; if(valRight)delete[]valRight; if(valTemp)delete[]valTemp; if(nextLevel)delete nextLevel; } ARRAY() { keyResult=NULL; keyLeft=NULL; keyRight=NULL; keyTemp=NULL; valResult=NULL; valLeft=NULL; valRight=NULL; valTemp=NULL; countResult=0; countLeft=0; countRight=0; len=0; nextLevel=NULL; } void set(unsigned int Key,unsigned int Val) { unsigned int*k=new unsigned int[1];k[0]=Key; unsigned int*v=new unsigned int[1];v[0]=Val; set(k,v,1); } unsigned int get(unsigned int Key) { unsigned int l,r,i; if(keyTemp) { l=0;r=len; while(l!=r-1) { i=(l+r)/2; if(keyTemp[i]<Key)l=i; else if(keyTemp[i]>Key)r=i; else return valTemp[i]; } if(keyTemp[l]==Key)return valTemp[l]; } if(keyLeft) { l=0;r=len; while(l!=r-1) { i=(l+r)/2; if(keyLeft[i]<Key)l=i; else if(keyLeft[i]>Key)r=i; else return valLeft[i]; } if(keyLeft[l]==Key)return valLeft[l]; } if(keyRight) { l=0;r=len; while(l!=r-1) { i=(l+r)/2; if(keyRight[i]<Key)l=i; else if(keyRight[i]>Key)r=i; else return valRight[i]; } if(keyRight[l]==Key)return valRight[l]; } if(nextLevel)return nextLevel->get(Key); else return undefined; } }; void main() { ARRAY*arr=new ARRAY; char inp[256]; unsigned int Key,Val; while(gets(inp)&&inp[0]) { if(inp[0]=='+'){Key=atoi(&inp[1]);gets(inp);Val=atoi(inp);arr->set(Key,Val);} else if(inp[0]=='='){Key=atoi(&inp[1]);Val=arr->get(Key);if(Val!=undefined)printf("%d\n",Val);else printf("undefined\n");} else system("cls"); } delete arr; }
PS:
いくつかの