[C ++]-ベクター、キュー、STLコンテナーのリスト

1. STL分類

c ++ STLは、標準テンプレートlibaray標準テンプレートライブラリとも呼ばれます。
以下、当社のC ++ STLコンテナに共通する上場
ここに画像の説明を挿入
ここに画像の説明を挿入
ここに画像の説明を挿入
実装オブジェクトのオープンメモリ空間を容器アロケータが配置されて解放し、容器・コンフィギュレーション・デストラクタ
メモリを割り当てることは責任を開き、
メモリ解放する責任dealocate
構造物の建設を
対象Destoryは破壊

第二に、ベクトル

1.基になるデータ構造が
動的に開発された配列で、ベクトルvecの容量が元のスペースサイズの2倍に拡張されるたびに
2.関連するインターフェースが
ここに画像の説明を挿入
増加します:
vec.push_back(20);コンテナーの最後に要素を追加O(1)によりコンテナーが拡張されます
vec.insert(it、20);イテレーターが指す位置に要素20 O(n)を追加し、コンテナーを拡張します

削除:
vec.pop_back();最後の要素O(1)を
削除しますvec.erase(it);イテレータが指す要素O(n)を削除します
注:コンテナの継続的な挿入または削除(挿入/消去)はイテレータを更新します。更新しない場合、最初の挿入または消去が完了します。イテレータは無効です

例1:vecコンテナー内のすべての偶数を削除することを実現

int main()
{
vector<int> vec;
auto it2 = vec.begin();
	while (it2 != vec.end())
	{
		if (*it2 % 2 == 0)
		{

			it2 = vec.erase(it2);
		}
		else
		{
			++it2;
		}
	}
	return 0;
}

vec.erase(it2)のみの場合、実行後にイテレーターが無効になるため、it2を追加できません。したがって、イテレータは1回更新する必要があり、削除後、次の要素は現在のイテレータの位置に移動されるため、it2 ++は使用されません。
さらに、現在の要素は判断を続けます。現在の要素が偶数でない場合、イテレータ++の
演算結果は次のようになります。
ここに画像の説明を挿入
例2:ベクトルコンテナー内のすべての奇数に奇数1未満の偶数を追加する(連続挿入)

int main()
{
vector<int> vec;
auto it1 = vec.begin();
	for (it1 = vec.begin(); it1 != vec.end(); ++it1)
	{
		if (*it1 % 2 != 0)
		{
			it1=vec.insert(it1, *it1 - 1);//要对迭代器进行更新
			it1++;
		}
	}
	return 0;
}

イテレータを更新します。下の図に示すように、奇数を見つけて2つの++演算を実行し、47を見つけてその前に46を挿入し、++ it1は46を挿入します。次の奇数。ここに画像の説明を挿入

クエリ:
演算子[];最下層は配列であるため、配列の最大の機能は、vec [5] O(1)
イテレータイテレータにランダムにアクセスして、配列の添え字
検索、for_each
foreach =>イテレータを介して実現します。

3.共通のメソッド
サイズ():コンテナーの下部にある有効なデータ要素を返します
empty():コンテナーが空であるかどうかを判断します
予約(20):ベクトルのスペースを予約すると、コンテナーの下部に指定されたサイズのメモリスペースのみが開かれ、新しいスペースは追加されません要素の
サイズ変更(20):コンテナの拡張により、指定されたサイズのメモリ空間がコンテナの下部に開かれるだけでなく、新しい要素の
交換が追加されます。2つのコンテナが要素を交換します

ここでは、予約とサイズ変更を特別に区別する必要があります。
予約は、主にベクターコンテナーのスペースを予約するためのものであり、次のコードを検証します。

int main()
{
	vector<int> vec;//默认开辟的vector,底层空间为0
	vec.reserve(20);

	cout << vec.empty() << endl;//输出布尔值
	cout << vec.size() << endl;
	
	for (int i = 0; i < 20; i++)
	{
		vec.push_back(rand() % 100 + 1);
	}
	cout << vec.empty() << endl;
	cout << vec.size() << endl;
	return 0;
}

実行結果は次のようになります
ここに画像の説明を挿入
。reserveはベクターコンテナー20のスペースを予約していますが、そこにはデータがないため、emptyはtrueであり、追加プロセスによって容量が増加することはありません。したがって、最終的にはまだ20名分の容量でした。

サイズ変更はコンテナの拡張であり、次のコード検証

int main()
{
	vector<int> vec;//默认开辟的vector,底层空间为0
	vec.resize(20);

	cout << vec.empty() << endl;//输出布尔值
	cout << vec.size() << endl;
	
	for (int i = 0; i < 20; i++)
	{
		vec.push_back(rand() % 100 + 1);
	}
	cout << vec.empty() << endl;
	cout << vec.size() << endl;
	return 0;
}

操作の結果は次のとおり
ここに画像の説明を挿入
です。20個のスペースが開かれるだけでなく、0個のプラスチック要素が20個格納され、20個の追加要素が
追加されると展開が開始されるため、空はfalseです。追加プロセスでは、さらに20個の要素追加されます。したがって、最終的な出力
は40.4になります。イテレーター
メソッド1を介してベクターコンテナーをトラバースします

auto it1 = vec.begin();
	for (; it1 != vec.end(); ++it1)
	{
		cout << *it1 << " ";
	}

方法2:

int size = vec.size();
	for (int i = 0; i < size; i++)
	{
		cout << vec[i] << " ";
	}

3、キューとリスト

1.両端キューコンテナーキュー

1.基礎となるデータ構造

動的に開発された2次元配列、1ビット配列は2から始まり、2倍に拡張されます。各拡張の後、元の2次元配列は、新しい1次元配列の添え字oldsize / 2から格納されますdequeの最初と最後の要素へのdeque deqの追加を容易にするために、同じ空白行が予約されています。
以下に示すように、キューがいっぱいになると、キューは下に拡張され
ここに画像の説明を挿入
ます両方のキューがいっぱいになると、
ここに画像の説明を挿入
2が拡張
ここに画像の説明を挿入
されます。関連するインターフェースが追加されます。
deq.push_back(20);末尾から要素O(1)を追加するdeq.push_front(20);要素Oを追加する(1)
//vec.insert(vec.begin(),20)O(n)
deq。 insert(it、20);要素O(n)を追加します

削除:
deq.pop_back();末尾から要素O(1)を削除するdeq.pop_front();
ヘッダーから要素O(1)
削除するdeq.erase(it);要素O(n)をポイントする位置から削除する

クエリ検索:
イテレーター(継続的な挿入と消去では、イテレーター障害の問題を考慮する必要があります)

2.リンクリストコンテナーのリスト

1.基礎となるデータ構造
図に示すように、次に双方向の双方向リンクリストのデータの前に:
ここに画像の説明を挿入
2.関連するインターフェースが
ここに画像の説明を挿入
追加されます:
mylist.push_back(20);末尾から要素を追加O(1)
mylist.push_front(20);ヘッドから要素を追加しますO(1)//
vec.insert(vec.begin( ) ,20 )O(n)mylist.insert(it、20);要素が指す位置に要素を追加O(1)リンクリストに挿入するときは、最初にクエリクエリ操作を実行する
リンクリストの場合、クエリ操作の効率は比較的遅い

削除:
mylist.pop_back();要素O(1)を末尾から削除しますmylist.pop_front();要素O(1)を
削除します
mylist.erase(it)を先頭から削除します;要素O(n)をポイントする位置から削除します

クエリ検索:
イテレーター(継続的な挿入と消去では、イテレーター障害の問題を考慮する必要があります)

ベクトルコンテナ以外の
デキューおよびリスト、関数インターフェイスの追加および削除:push_frontおよびpop_fornt

4、ベクター、キュー、リストの違い

1. vectorとdequeの違い

ベクトル機能:動的に開発された配列、メモリは連続的、容量はベクトルvecの2倍に拡張されます。

Dequeの機能:動的に開発された2次元配列空間、dequeの最下部のメモリは連続的ではない、 2番目の次元は固定長配列空間、拡張時(1番目の次元の配列の二重拡張)
1、基礎となるデータ構造の違い
2 3.前、後、
中、最後に要素を挿入する時間の複雑さは O(1)と同じです。両端キューを前または後に拡張できるため、前に挿入デキューはO(1)ですが、vectorO(n)

3.
メモリの使用効率を上げるために、ベクターに必要なメモリ空間は連続的である必要があり、デキューはデータストレージ用にブロックに分割できます。連続的なメモリ空間は必要ありません

4.途中で挿入または消去します。効率ベクトルが良くなり、両端キューが悪くなります。
時間の複雑さはO(n)ですが、移動の利便性を考慮する必要があります。両端キューの2次元のメモリ空間は連続的ではないため、両端キューの途中で要素を挿入または削除すると、要素の移動がベクトルより遅くなります。
次の図に示すように、
ここに画像の説明を挿入
dequeでは、各2番目の次元は連続(更新)であり、区分的に連続です。
要素が削除され、次の要素の動きが最初に1次元で検出され、開始位置のアドレスが格納され、次にオフセットに従って要素の動き位置が検出されます。
ただし、次の図に示すように、ベクターの削除は非常に簡単です。
ここに画像の説明を挿入
彼のストレージスペースは連続しているため、1つずつ順番に移動できます。

2.ベクトルとリストの違い

これら2つの違いは、配列とリンクリストの違いに似ています。このような関連付けにより、答えを簡単に得ることができます。

1.基本となるデータ構造
1つは動的配列で、もう1つは二重循環リンクリストです。

2.時間の複雑さを追加、削除、変更する

配列増加削除O(n)クエリO(n)ランダムアクセスO(1)
リンクリストは検索時間を考慮する残りの削除クエリ時間の複雑さはO(1)

公開された98元の記事 ウォンの賞賛9 ビュー3659

おすすめ

転載: blog.csdn.net/qq_43412060/article/details/105266945