C#の共通のデータ構造を解析します

:この記事は、接続に再現され  https://blog.csdn.net/suifcd/article/details/42869341

はじめに:
このデータ構造の概要については、ブログを読んで、すべての人のオイルの小さなポットてきたかもしれないが、すべての人は急いで少し記事を書くには少し時間だったので、今日は牛に再発行され、いくつかの追加や変更を行いました。プログラム猿として、共通のデータ構造を習得することが必要である、おそらくこの記事ビットのシンプルな、ない空想の物事ので、しかし、すべての人にも少しの希望、そのプログラムにU3Dのそれのような専門家。
小さな男前にいくつかの時間は、コードに様々なデータ構造と賞賛の柔軟な使用を読んで、だけでなく、大幅にソートに様々な小さなデータ構造のためのすべての男の欲望を刺激してまとめることができます。つい最近、私は、共通のデータ構造は、自分自身のために緊急になる使用の柔軟性をまとめることを、偉大な神の記事の数を読みました。まだシナリオデータ構造について話をするすべての人、およびデータ構造の多様性は、通常、U3Dが頻繁にそれを使用して使用し、作業内容を開始するための初期の時代です。
1.いくつかの共通のデータ構造 
ここでは主に、多くの場合、すべての人の仕事で遭遇いくつかの小さなデータ構造をまとめたもの:配列、ArrayListを、リスト<T >、LinkedListは<T>、キュー<T>、スタック<T>、辞書<K、T>
配列アレイ:  
アレイは、最も単純なデータ構造です。これは次の特性があります。

  • 配列は連続したメモリに格納されています。
  • 配列の内容は同じタイプです。
  • アレイは、インデックスを介して直接アクセスすることができます。

  創造の配列アン配列:

int size = 5;

int[] test = new int[size];

あなたが作成すると、新しい配列は、サイズのブルーム量、配列要素の宣言された型の型に連続したメモリ空間をヒープ管理CLRに割り当てられます。型は値型のこの型の値がある場合は、サイズが作成される箱なしがあるでしょう。型が参照型である場合、参照型が作成され、対応する大きさが存在することになります。
  それは非常に速いスピードをインデックスですので、それは、連続したメモリストレージにあるので、アクセス時間は関係なく、配列内の要素、および割り当ての数の定数であり、要素を変更するシンプルな元素です。

string[] test2 = new string[3];

//赋值

test2[0] = "chen";

test2[1] = "j";

test2[2] = "d";

//修改

test2[0] = "chenjd";

しかし、利点がありますが、それは欠点を添付しなければなりません。それが連続して格納されているため、新たな要素が二つの要素の間に挿入されるので、不便になります。そして、ショー、上記のコードのように、あなたは新しい配列を宣言するとき、あなたはその長さを指定する必要があり、これは可能性があります問題は、私たちは長さを宣言するときには、あるときに我々が長すぎる、明らかに、メモリの無駄になります時間の短すぎる長さ、オーバーフローのリスクを宣言しました。これは、投機のようなコードを書くことになり、非常に小さな男は、このような行動を嫌うことができます!この欠点を考慮すると、以下の壮大な打ち上げのArrayList。
ArrayListの:  
欠点に対処するためには、配列の長さを指定する必要がありますが、同じタイプとデータ構造の導入を作成して保存することができます。にSystem.Collectionsを使用するために導入されなければならないので、ArrayListのは、にSystem.Collections名前空間の下の部分です。上述したように、ArrayListのアレイの欠点のいくつかを解決します。

  • ArrayListオブジェクトの長さに起因するのArrayListを宣言するとき、その長さを指定せずにダイナミックな成長に格納された縮小データに従ってあります。
  • ArrayListの要素の種類を保存することができます。それはに対処するためのオブジェクトなどの要素をArrayListになるからです。従って、異なる種類の元素の添加が許可されています。

  ArrayListの操作:

ArrayList test3 = new ArrayList();

//新增数据

test3.Add("chen");

test3.Add("j");

test3.Add("d");

test3.Add("is");

test3.Add(25);

//修改数据

test3[4] = 26;

//删除数据

test3.RemoveAt(4);

彼はとても「利点」の束が、また、それの欠点についての話を語りました。なぜ与える「利点」は、引用符にそれをマーク?その理由は、ArrayListには、異なるタイプのデータを格納できるためであるとの取引を行うためのオブジェクトなど、すべての種類に起因して、ArrayListの要素は、実際にはObject型の問題が来た何スパイシーされていると言うことです。

  • ArrayListのは、タイプセーフではありません。オブジェクトが行うとして、異なるタイプの処理されるので、状況はArrayListのを使用するときに可能性の高いタイプの不一致が発生しています。
  • パッキングストレージアレイの値の型が、オブジェクトとしてArrayListの以降のすべてのタイプ、値型ボクシング操作を挿入する際に必然的に起こるが、分割がインデックスのときの値を発生した場合、本明細書の苦情として、発生しませんでしたボックス操作。あなたは行うことができるかもしれませんか?

注:なぜ頻繁に不要なボクシングとアンボクシング缶がそれを負担されていませんか?いわゆる梱包(ボクシング):コンバージョンの種類(Baiduの百科事典)にオブジェクトインスタンスの値である来るすべての人にゆっくりと小さな聞きます。そうアンボクシング:参照型は、わずかに値型に変換される(またはBaiduの百科事典から)。以下は〜栗です

//装箱,将String类型的值FanyoyChenjd赋值给对象。

String  info = ”FanyoyChenjd”; 

object obj=(object)info; 

 

//拆箱,从Obj中提取值给info

object obj = "FanyoyChenjd";

String info = (String)obj;

そして、結論?さて、再びBaiduの百科事典ローにすべての人の非常に少ないの参照をしましょう。それは、パッキンは、減少し効率が得られている時間を、失っている参照オブジェクトの新しい世代であるとき、原則から明らかです。

リスト<T>一覧ジェネリック  
新しい配列型として導入ボクシングとアンボクシングの安全ではないのArrayList型の欠点を解決するために、したがって、一般的な概念、。アレイは、多くの場合、仕事の種類で使用されています。そしてArrayListに非常に類似した長さが変化に柔軟であることができ、最大の違いは、あなたがリストのコレクションを宣言するとき、我々はまた、データ宣言リストのセット内のオブジェクトの種類、および配列のために必要な、これは、実際には、リスト<T>内部に非常に似ているということです達成するために配列を使用しています。

List<string> test4 = new List<string>(); 

   

//新增数据 

test4.Add(“Fanyoy”); 

test4.Add(“Chenjd”); 

 

//修改数据 

test4[1] = “murongxiaopifu”; 

   

//移除数据 

test4.RemoveAt(0);

最大の利点は、そうすることです

  • 型の安全性を確保。
  • また、動作ボクシングとアンボクシングをキャンセル。
  • これは、アレイの利点は、柔軟性と長さArrayListの変化の利点への迅速なアクセスを提供し兼ね備えています。

普通の人、最も一般的な作業で使用されるデータ構造のように、あなたと小さなを仮定します。だから、再び我々はもう少し好奇心をすれば?のは、探検することを何、もし我々どこからそれを開始するための同様のデータ構造の独自の実現?
議論を開始するための小さな普通の人がここに。
ただ、私たちの単純な実装がそう内部リスト<T>は、実際に配列され、強く型付けされた、と述べた(のがそれを呼びましょうEggArray <T>)も、この機能に付着し、内部はアレイによって達成され、型を宣言する必要があります。しかし、我々はまた、<T>継承リストを見ると、このようなIEnumerableをインタフェースなどのインタフェース、および値型と参照型-テイク全ての数を実装しています。ここでEggArrayへ<T>軽く武装シンプルなラインを実現する当社のEggArrayのみ参照型を提供しながら、私たちは、リスト<T>を継承各種インターフェース継承しません。
まあ最初のオールクリアの、それは参照型の処理で、ジェネリックを達成するために。次に出てきた定義します。

//EggArray类

//定义

public class  EggArray<T> where T : class

{

}

次のステップは、そう?その内部のメンバーの決意、そしてフィールドで開始するとプロパティが始まります。
プロパティ&変数

プロパティ 説明
容量 EggArray容量
カウント EggArrayの要素数
アイテム

記事では、内部リスト<T>を言ったように、我々はまた、内部配列を使用してT []、Arrayには、それは、まだ配列であります

 

 

 

 get

    {

        return this.count;

    }

}

 

public int  Capacity

{

    get

    {

        return this.capacity;

    }

}

その後、何?コンストラクタが必要であると思われます。それは容量を指定する必要はないときも、私は、上記の新しいのようなルックスを言いました。だから我々はコンストラクタはとてもそれが作ら置きます。
コンストラクタ:

コンストラクタ 説明
EggArray() 初期EggArray <T>クラスの新しいインスタンスは、インスタンスが空で、デフォルトの初期容量を持っています。
EggArray(INT32)

初期EggArray <T>クラスの新しいインスタンスは、インスタンスが空で、指定された初期容量を持っています。

 

 

//EggArray的构造函数,默认容量为8

public EggArray() : this(8)

{

}

 

public EggArray(int capacity)

{

    this.capacity = capacity;

    this.items = new T[capacity];

}

すべてのプライベート操作機構物流への道があるのでまあ、また終了コンストラクタは、その後、民間の方法を教え、公共の方法は、当社の使用のみにのみ営業しています。小さな普通の人には示さない、ここで共通のアプローチを達成するには興味がありません。
ただ、また言った、リスト<T>初期の長さが問題で、あなたが使用することができます追加されません()メソッドは、要素を追加し、入力されたが、それを格納するために無限の空間を持つことは不可能である、それは何を意味しており、何を行うことができますこれはありますか?動的内部配列のサイズを調整する方法があるため存在し、倍増に応じて原稿サイズの長さを調整します。呼び出しリサイズしてみましょう。
したがって、次の内容の前に、小さな普通の男はあなたに質問をしたいと思います:

List<int> test = new List<int>(){0,1,2,3,4,5,6,7,8,9};

                int count = 0;

                for(int i = 0; i < test.Count; i++)

                {

                        if(i == 1)

                                test.Remove(test[i]);

                        count++;

                }

                Debug.Log (count);

どのような上記のコードが出力されますそれは?答えは9です。テストの長さは、ああ、明らかに10ある行くことにすると、一部のオイル流域は、驚くかもしれません。あなたは要素を削除してもの間、なぜその背後にある要素に影響を与えるのだろうか?(たとえば、上の1に現在のインデックス2の要素のための元のインデックスオフ素子1削除するための指標)が木材の混乱感?実際には、ここではリスト<T>削除するだけでなく、配列の内部圧縮を実行している間。だから、確かにわずかに圧縮するために使用する方法があります。私たちは、暫定的にコンパクトと呼ばれます。
プライベートメソッド

プライベートメソッド 説明
リサイズ 配列の要素の数よりも大きいかまたはアレイの容量に等しい場合、拡張のためのメソッド呼び出しは、新しいデータ・ストレージ・アレイを作成し、「成長因子」とは、2であります
コンパクト デフォルトの時間の削除と呼ばれるパックアレー、

//当数组元素个[/size][/backcolor][/color][i][color=White][backcolor=DarkGreen][size=2]数不小于数组容量时,需要扩容,增长因子growthFactor为2

private void  Resize()

{

    int capacity = this.capacity * growthFactor;

    if (this.count > capacity)

    {

        this.count = capacity;

    }

    T[] destinationArray = new T[capacity];

    Array.Copy(this.items, destinationArray, this.count);

    this.items = destinationArray;

    this.capacity = capacity;

}

 

 private void  Compact()

        {

            int num = 0;

            for (int i = 0; i < this.count; i++)

            {

                if (this.items[i] == null)

                {

                    num++;

                }

                else if  (num > 0)

                {

                    this.items[i - num] = this.items[i];

                    this.items[i] = null;

                }

            }

            this.count -= num;

        }[i][i][i]

LinkedListは<T>は  
、リンクされたリストです。そして最大配列は、不連続であってもよいソート・メモリに記憶されている上記のリストは異なっています。インデックスにアクセスすることができない場合があり、素子配置の次の要素に1ポイント鎖によるものです。フィギュア

最大の特徴リストはメモリ空間に格納されているので、必ずしも連続的でないし、長所と短所の最大の配列にリスト相対的には明白です。

  • 構造の容量を調整することなく、リストまたは削除ノードに挿入。店舗自体は連続が、各オブジェクトのポインタの決定によるものであるため、そう要素を追加および削除要素はアレイ上の利点を有していなければなりません。
  • 状況の秩序の並べ替えに必要な新しい要素を追加し、比較を行うために取得の配列もあり、例えば、配列の真ん中に新しい要素のどこかを追加するために、あなたは要素の移動の多くを移動する必要がある、と可能性の点ではリストのためにも用一覧ただ唯一の変更のいくつかの要素を指します。
  • それは必ずしもメモリ空間に直列に配置されていないため、長所短所があります、インデックスを使用することはできませんが、スクラッチ・ノードから開始するアクセス時間は、次の連続するトラバースまでのノードがターゲットを見つけるために。だから、あなたは確かに利点オブジェクト、配列、にすばやくアクセスする必要がある場合。

  要約すると、リスト要素の固定数には適していない、そしてしばしば両端アクセスノードを増減する必要があります。
  リストを使用するには、MSDNの詳細な例があります。
キュー<T>  
にキュー<T>このデータ構造は、最初の要素を削除する最初に挿入され、そうでない場合は最後に挿入された要素が最後に除去されるので、キューは「先入れ先出し」として知られています(FIFO-形リニア)最初のうちで最初に。これらの2つの方法を使用して、キュー<T>エンキューおよびデキューへのアクセスを達成するために。

に注意を払うためにいくつかの必要性:

  • FIFOのシナリオ。
  • デフォルトでは、キュー<T> 32の初期容量、2.0の成長因子。
  • エンキューを使用する場合より少ない場合には、例えば、キュ​​ーの容量の初期2.0、次いで2倍の増加容量を増加させるために成長因子に基づいて、キューの長さが十分であるか否かを判定する。
  • 精彩を欠きました。

  

  
辞書<K、T>  
小さいながらも非常に、非常に普通の人のような辞書この事、。後、削除、非常に好まれていない、彼らは辞書にだと思うものを私に知らせる辞書を入力することができます作成し、物事を投げ、追加、アクセスが高速にジレと呼ばれています。しかし、数日前まで、それは彼女がフレーズ思い出したことを、少し普通の人に、物品の神を見て、「あなたは、あなたがたを占めていることが良いことは、それを作る何を。」だから、辞書霧の背後に隠されているものの端に、そして重い霧を突くかどうか、真実はありますか?のは、次のポイントを聞いてみましょう。など、私たちは以下の辞書を調べてみましょう必要があります。
  辞書の実装は、ハッシュテーブルの実装があるので、言及した辞書は、Hashtableのハッシュテーブルとハッシュ(ハッシュとも呼ばれるハッシュを)言っているだろうが、作成時に辞書がどの手段は、タイプセーフでありますとき辞書には、最初の辞書とハッシュテーブルの間の差である、キーと項目の型を宣言する必要があります。このブログのハッシュテーブルで推奨表情のコンテンツハッシュテーブルについて。ハッシュについては、単に単語のインデックスにそれぞれ番号が対応する場合、例えば00000から99999までの学校の生徒数の範囲として固定長圧縮、5つの数字の合計に対する任意の長さのメッセージの一種です、次いで、インデックス100 000であるが、我々はインデックスとして3を使用する場合、インデックスの範囲は999から000になり、当然のことながら、矛盾する場合は、状況がハッシュ衝突(ハッシュ衝突)です。具体的な実装原理上、離れて引っ張ると小さな男は、大きなもの、私はブログのターン語はかなりまぶしい読むことを、当然のことながら、エッセイのブログをお勧めすることができます参照することです。
  戻る辞書に<K、T>、我々はそれがある場合は、その弱点を享受してきた時の様々な辞書利点で動作しますか?ルの場合は、スペースです。時間のためのスペース、スピードの追求を満たすために、より多くのメモリオーバーヘッド。あなたは辞書を作成するとき、我々は、静電容量値を渡すことができますが、容量の実際の使用は、値ではありません。しかし、実際の容量は、直接インデックスを実装するが、追加の2列を作成していない(趙)、「最小の素数の実際の容量の値が使用されているように、最小値は3である。以上」の使用を間接的な指標、すなわちINT []バケットおよびエントリ[]エントリ二つの配列(すなわち、実際には、保存されたバケットのインデックスエントリアレイ)は、第二辞書とハッシュテーブルとの間の差はこちらを達成するために、ハを覚えギリシャの競合?はい、2つ目の違いは、ポリシー処理ハッシュ衝突が異なることです!各辞書の位置をマッピングされたバケットが、次に各バケットため辞書は、今述べたバケットのバケットのアレイの一つ、及びバケットの長さは、辞書の真の長さであるハッシュ衝突に対処するために、追加のデータ構造を使用します同じ記憶素子、記憶及び再分配のハッシュのリストである要素。

したがって、状況の私たちの顔は、我々は空の辞書を作成した場合でも、その後、長さ3の2つの配列を伴う、ということです。だから、少しデータを処理するとき、または慎重にも辞書を使用し、許容も多くの場合、配列を使用して。

2.いくつかのデータ構造の一般的な使用シナリオ

アレイ 処理する要素の数を決定すると考えられ、添え字の使用を必要とするかもしれないが、我々はリスト<T>を使用することをお勧めします
配列リスト リスト<T>を使用することをお勧めします、お勧めできません
リスト<T>ジェネリック一覧 処理されるべき要素の数は、一般的に不確実な使用することをお勧めします
LinkedListは<T> 要素数のリストは、固定されていないノードでの頻繁な変更の必要性は、第二の端部は、増加または減少させることができる場合
キュー<T> FIFOケース
スタック<T> LIFOケース
辞書<K、T> 操作は、高速キーと値のペアが必要です


記事から転載、共通のデータ構造Daqiディ-すべての人の精巧なUnity3D(4) 感謝[でき慕容小さな男]良い記事を提供します

リリース6元記事 ウォンの賞賛189 ビュー280 000 +

おすすめ

転載: blog.csdn.net/newbie_xymt/article/details/103687770