====== リスト構造 ====== ハッシュテーブルを作る際に、ハッシュ値が被った時の処理を考えると、\\ 自由に要素を追加可能なデータ構造が欲しくなるよね\\ こんなかんじの list[0]:〇→〇 list[1]:〇→〇→〇 list[2]:〇 list[3]:〇→〇 list[4]:〇→〇→〇 list[5]:〇 list[6]:〇→〇 list[7]:〇 そうだ、そんなときはリスト構造を使おう!\\ リスト構造は、データをアドレスでつないだ構造をしています。\\ 一番オーソドックスなリスト構造(単方向リスト)\\ h:head\\ t:tail\\  [ h ]→ [ 1 ]→ [ 3 ]→ [ 5 ]→ [ 7 ]→ [ t ]\\ \\ データ単体は以下のような形になります。\\ 118       アドレス   [ 9 ]→NULL [ データ値]→NULL                ↑Next(次のデータのアドレス、初期値はNULL) * NULL: * 何も指さないアドレス。数値みたいに0とかで初期化しようと思っても、0番地にもデータが入ってるかもしれないので、0は使えない。。。 * そのために、どこにも属してないよってアドレスを表すものが必要。ってことで用意されたのがNULL リスト型のデータを1個だけ作ると、どこかのアドレスにこんな感じのデータが1個作られます。\\ アドレス   [ データ値]→NULL       ↑Next(次のデータのアドレス、初期値はNULL) たとえば、アドレス0x022にデータが作られて、データ値を3で初期化して使おうとすると以下のようになります。\\ 値は 022   [ 3 ]→NULL       ↑Next(次のデータのアドレス、初期値はNULL) ---- ここから書きかけ  head:ヘッド(データがここからつなっていく、「はじめ」を表すデータのアドレス) tail:テール(データの終わりを表すでーたのアドレス)  データ: アドレス部 データ部 ネクス部 でできているよ   アドレス部:データ自身のアドレス    データ部:格納したい値   ネクスト部:次のデータのアドレス  整数 [ 1,3,5,7 ] がリストになっているイメージ  h→1→3→5→7→t アクセス法  ①headのデータアドレスを取得 ②headのnextを見る(最初のデータにアクセスできる)  ③nextのデータのnextを見る(次のデータにアクセスできる)  ④ …  ⑤nextがtailになったらそれ以上データはないよ    今見ているアドレスを変数にしてたどっていく 031 013 A15 FF2 109 BAD アドレス(16進)  [ h ]→ [ 1 ]→ [ 3 ]→ [ 5 ]→ [ 7 ]→ [ t ] 013 A15 FF2 109 BAD   ↑iterator  Crr = head if(Crr.next != tail) Crr = Crr.next if(crr.data == 5)5の時の処理 データの追加 031 013 A15 FF2 109 BAD アドレス(16進)  [ h ]→ [ 1 ]→ [ 3 ]→ [ 5 ]→ [ 7 ]→ [ t ] 013 A15 FF2 109 BAD  headとtailのアドレスは知っているとき、  リスト構造のデータを用意 整数データ 9 を追加   118  [ 9 ]→NULL (NULLはどこにもつながっていないよというアドレス(数値でいう0))  nextがtailになっているデータにつなぐ! if(Crr.next == tail) Crr.next = 118 (Crr:109 Crr.next:118) Crr = Crr.next (Crr:118 Crr.next:NULL) Crr.next = tail (Crr:118 Crr.next:tail) ==== リスト構造の種類 ==== 呼ばれ方\\ ネットを見るといろいろ表記ゆれがありますが、基本的に以下のものは同じリスト構造を指します。\\ *リスト構造 *リンクリスト *リンクトリスト *連結リスト *リスト リスト構造の種類\\ * 単方向リスト * リンクの方向が一方向に決まっているもの * 前方リンクと後方リンクがある * 単方向循環リスト * リンクの最後のデータと最初のデータが円環状につながっているもの、一方向にしかたどれない * 前方リンクと後方リンクがある * 双方向リスト * リンクの方向が前後方向のもの、データをたどるときに1個前と1個先のデータへリンクされている * 双方向循環リスト * 循環リスト ==== 配列VSリスト ==== 配列とリストの違い ==== イテレータを使って、nextのデータにアクセスしていくソースコード ==== #include #include using std::cout; using std::cin; using std::endl; using std::list; //STLのlistを使うよっていうinclude //テンプレート(いろんな方に対応できる便利な奴) int main() { //intのリストを作りたいな list ilist; //floatのリストを作りたいな //list flist; int indata; do{ cout << "整数を入力:"; cin >> indata; if(indata != -1) ilist.push_back(indata); else break; }while(true); list::iterator theI = ilist.begin(); cout << *theI << endl; //*theI theIのアドレスの中身のデータを取り出す theI = std::next(theI); //theI++ cout << *theI << endl; //cout << ilist[2] << endl; ランダムアクセスはできん! }