目次
2.17priority_queue(プライオリティキュー)
I. 概要
シーケンスコンテナ | 順序付けられた連想コンテナ | 順序付けされていない連想コンテナ | コンテナアダプター | |
---|---|---|---|---|
特徴 | 1. 実数値のみ 2. 並べ替えを行わない 3. コンテナ内の位置に基づいて要素を順番に保存し、アクセスする |
1. キーと値のペア (key、val) 2. 内部自動仕分け 3. キーによる保存と読み取り 3. データをキー値の形式で保存します。つまり、キーワードを値に関連付けて保存できます。 |
コンテナテンプレート コンテナのコンテナ コンテナインターフェース |
|
構造 | 要素間の順序関係を持つ線形リストは、線形構造の順序付けられたクラスターです。 | 連想コンテナは非線形ツリー構造、より正確にはバイナリ ツリー構造です。 |
||
容器 | 1、配列 2、ベクトル 3 4、リスト 5、forward_list |
1.マップ(独自要素) 2.set(独自要素) 3. マルチマップ (要素を繰り返すことができます) 4. マルチセット (要素を繰り返すことができます) |
1、unordered_map 2、unordered_set 3、unordered_multimap 4、unordered_multiset |
(インターフェース) 1、スタック 2、行列 3、優先キュー |
1階 | 赤黒い木 | ハッシュ表 | ||
知らせ: 1. set と map の違い: map はキーと値のペア <key, val> で、set もキーと値のペアですが、key=val です。 2. マルチがある場合とない場合の違い: マルチがある場合は、コンテナ内の要素を繰り返すことができることを意味します。 3. 順序なしと順序なしの違い: 順序なしとは、コンテナ内の要素が自動的に並べ替えられないことを意味します。 |
2. テンプレート
2.0 string( string - C++ リファレンス)
std::string s0 ("Initial string");
// constructors used in the same order as described above:
std::string s1;
std::string s2 (s0);
std::string s3 (s0, 8, 3);
std::string s4 ("A character sequence");
std::string s5 ("Another character sequence", 12);
std::string s6a (10, 'x');
std::string s6b (10, 42); // 42 is the ASCII code for '*'
std::string s7 (s0.begin(), s0.begin()+7);
2.1アレイ
template < class T, size_t N > class array;
2.2ベクトル
template < class T, class Alloc = allocator<T> > class vector; // generic template
// constructors used in the same order as described above:
std::vector<int> first; // empty vector of ints
std::vector<int> second (4,100); // four ints with value 100
std::vector<int> third (second.begin(),second.end()); // iterating through second
std::vector<int> fourth (third); // a copy of third
// the iterator constructor can also be used to construct from arrays:
int myints[] = {16,2,77,29};
std::vector<int> fifth (myints, myints + sizeof(myints) / sizeof(int) );
2.3デク
template < class T, class Alloc = allocator<T> > class deque;
std::deque<int> mydeck (3,100); // deque with 3 elements
std::list<int> mylist (2,200); // list with 2 elements
std::queue<int> first; // empty queue
std::queue<int> second (mydeck); // queue initialized to copy of deque
std::queue<int,std::list<int> > third; // empty queue with list as underlying container
std::queue<int,std::list<int> > fourth (mylist);
2.4リスト
template < class T, class Alloc = allocator<T> > class list;
// constructors used in the same order as described above:
std::list<int> first; // empty list of ints
std::list<int> second (4,100); // four ints with value 100
std::list<int> third (second.begin(),second.end()); // iterating through second
std::list<int> fourth (third); // a copy of third
// the iterator constructor can also be used to construct from arrays:
int myints[] = {16,2,77,29};
std::list<int> fifth (myints, myints + sizeof(myints) / sizeof(int) );
2.5forward_list
template < class T, class Alloc = allocator<T> > class forward_list;
std::forward_list<int> first; // default: empty
std::forward_list<int> second (3,77); // fill: 3 seventy-sevens
std::forward_list<int> third (second.begin(), second.end()); // range initialization
std::forward_list<int> fourth (third); // copy constructor
std::forward_list<int> fifth (std::move(fourth)); // move ctor. (fourth wasted)
std::forward_list<int> sixth = {3, 52, 25, 90}; // initializer_list constructor
2.7マップ
template < class Key, // map::key_type
class T, // map::mapped_type
class Compare = less<Key>, // map::key_compare
class Alloc = allocator<pair<const Key,T> > // map::allocator_type
> class map;
#include <iostream>
#include <map>
bool fncomp (char lhs, char rhs) {return lhs<rhs;}
struct classcomp {
bool operator() (const char& lhs, const char& rhs) const
{return lhs<rhs;}
};
int main ()
{
std::map<char,int> first;
first['a']=10;
first['b']=30;
first['c']=50;
first['d']=70;
std::map<char,int> second (first.begin(),first.end());
std::map<char,int> third (second);
std::map<char,int,classcomp> fourth; // class as Compare
bool(*fn_pt)(char,char) = fncomp;
std::map<char,int,bool(*)(char,char)> fifth (fn_pt); // function pointer as Compare
return 0;
}
2.8マルチマップ
template < class Key, // multimap::key_type
class T, // multimap::mapped_type
class Compare = less<Key>, // multimap::key_compare
class Alloc = allocator<pair<const Key,T> > // multimap::allocator_type
> class multimap;
#include <iostream>
#include <map>
bool fncomp (char lhs, char rhs) {return lhs<rhs;}
struct classcomp {
bool operator() (const char& lhs, const char& rhs) const
{return lhs<rhs;}
};
int main ()
{
std::multimap<char,int> first;
first.insert(std::pair<char,int>('a',10));
first.insert(std::pair<char,int>('b',15));
first.insert(std::pair<char,int>('b',20));
first.insert(std::pair<char,int>('c',25));
std::multimap<char,int> second (first.begin(),first.end());
std::multimap<char,int> third (second);
std::multimap<char,int,classcomp> fourth; // class as Compare
bool(*fn_pt)(char,char) = fncomp;
std::multimap<char,int,bool(*)(char,char)> fifth (fn_pt); // function pointer as comp
return 0;
}
2.9セット
template < class T, // set::key_type/value_type
class Compare = less<T>, // set::key_compare/value_compare
class Alloc = allocator<T> // set::allocator_type
> class set;
#include <iostream>
#include <set>
bool fncomp (int lhs, int rhs) {return lhs<rhs;}
struct classcomp {
bool operator() (const int& lhs, const int& rhs) const
{return lhs<rhs;}
};
int main ()
{
std::set<int> first; // empty set of ints
int myints[]= {10,20,30,40,50};
std::set<int> second (myints,myints+5); // range
std::set<int> third (second); // a copy of second
std::set<int> fourth (second.begin(), second.end()); // iterator ctor.
std::set<int,classcomp> fifth; // class as Compare
bool(*fn_pt)(int,int) = fncomp;
std::set<int,bool(*)(int,int)> sixth (fn_pt); // function pointer as Compare
return 0;
}
2.10マルチセット
template < class T, // multiset::key_type/value_type
class Compare = less<T>, // multiset::key_compare/value_compare
class Alloc = allocator<T> > // multiset::allocator_type
> class multiset;
#include <iostream>
#include <set>
bool fncomp (int lhs, int rhs) {return lhs<rhs;}
struct classcomp {
bool operator() (const int& lhs, const int& rhs) const
{return lhs<rhs;}
};
int main ()
{
std::multiset<int> first; // empty multiset of ints
int myints[]= {10,20,30,20,20};
std::multiset<int> second (myints,myints+5); // pointers used as iterators
std::multiset<int> third (second); // a copy of second
std::multiset<int> fourth (second.begin(), second.end()); // iterator ctor.
std::multiset<int,classcomp> fifth; // class as Compare
bool(*fn_pt)(int,int) = fncomp;
std::multiset<int,bool(*)(int,int)> sixth (fn_pt); // function pointer as Compare
return 0;
}
2.11unordered_map
template < class Key, // unordered_map::key_type
class T, // unordered_map::mapped_type
class Hash = hash<Key>, // unordered_map::hasher
class Pred = equal_to<Key>, // unordered_map::key_equal
class Alloc = allocator< pair<const Key,T> > // unordered_map::allocator_type
> class unordered_map;
#include <iostream>
#include <string>
#include <unordered_map>
typedef std::unordered_map<std::string,std::string> stringmap;
stringmap merge (stringmap a,stringmap b) {
stringmap temp(a); temp.insert(b.begin(),b.end()); return temp;
}
int main ()
{
stringmap first; // empty
stringmap second ( {
{"apple","red"},{"lemon","yellow"}} ); // init list
stringmap third ( {
{"orange","orange"},{"strawberry","red"}} ); // init list
stringmap fourth (second); // copy
stringmap fifth (merge(third,fourth)); // move
stringmap sixth (fifth.begin(),fifth.end()); // range
std::cout << "sixth contains:";
for (auto& x: sixth) std::cout << " " << x.first << ":" << x.second;
std::cout << std::endl;
return 0;
}
2.12unordered_multimap
template < class Key, // unordered_multimap::key_type
class T, // unordered_multimap::mapped_type
class Hash = hash<Key>, // unordered_multimap::hasher
class Pred = equal_to<Key>, // unordered_multimap::key_equal
class Alloc = allocator< pair<const Key,T> > // unordered_multimap::allocator_type
> class unordered_multimap;
#include <iostream>
#include <string>
#include <unordered_set>
template<class T>
T cmerge (T a, T b) { T t(a); t.insert(b.begin(),b.end()); return t; }
int main ()
{
std::unordered_set<std::string> first; // empty
std::unordered_set<std::string> second ( {"red","green","blue"} ); // init list
std::unordered_set<std::string> third ( {"orange","pink","yellow"} ); // init list
std::unordered_set<std::string> fourth ( second ); // copy
std::unordered_set<std::string> fifth ( cmerge(third,fourth) ); // move
std::unordered_set<std::string> sixth ( fifth.begin(), fifth.end() ); // range
std::cout << "sixth contains:";
for (const std::string& x: sixth) std::cout << " " << x;
std::cout << std::endl;
return 0;
}
2.13unordered_set
template < class Key, // unordered_set::key_type/value_type
class Hash = hash<Key>, // unordered_set::hasher
class Pred = equal_to<Key>, // unordered_set::key_equal
class Alloc = allocator<Key> // unordered_set::allocator_type
> class unordered_set;
#include <iostream>
#include <string>
#include <unordered_set>
template<class T>
T cmerge (T a, T b) { T t(a); t.insert(b.begin(),b.end()); return t; }
int main ()
{
std::unordered_set<std::string> first; // empty
std::unordered_set<std::string> second ( {"red","green","blue"} ); // init list
std::unordered_set<std::string> third ( {"orange","pink","yellow"} ); // init list
std::unordered_set<std::string> fourth ( second ); // copy
std::unordered_set<std::string> fifth ( cmerge(third,fourth) ); // move
std::unordered_set<std::string> sixth ( fifth.begin(), fifth.end() ); // range
std::cout << "sixth contains:";
for (const std::string& x: sixth) std::cout << " " << x;
std::cout << std::endl;
return 0;
}
2.14unordered_multiset
template < class Key, // unordered_multiset::key_type/value_type
class Hash = hash<Key>, // unordered_multiset::hasher
class Pred = equal_to<Key>, // unordered_multiset::key_equal
class Alloc = allocator<Key> // unordered_multiset::allocator_type
> class unordered_multiset;
#include <iostream>
#include <string>
#include <unordered_set>
template<class T>
T cmerge (T a, T b) { T t(a); t.insert(b.begin(),b.end()); return t; }
int main ()
{
std::unordered_multiset<std::string> first; // empty
std::unordered_multiset<std::string> second ( {"red","green","blue"} ); // init list
std::unordered_multiset<std::string> third ( {"red","yellow","blue"} ); // init list
std::unordered_multiset<std::string> fourth ( second ); // copy
std::unordered_multiset<std::string> fifth ( cmerge(third,fourth) ); // move
std::unordered_multiset<std::string> sixth ( fifth.begin(), fifth.end() ); // range
std::cout << "sixth contains:";
for (const std::string& x: sixth) std::cout << " " << x;
std::cout << std::endl;
return 0;
}
2.15スタック(スタック)
template <class T, class Container = deque<T> > class stack;
std::deque<int> mydeque (3,100); // deque with 3 elements
std::vector<int> myvector (2,200); // vector with 2 elements
std::stack<int> first; // empty stack
std::stack<int> second (mydeque); // stack initialized to copy of deque
std::stack<int,std::vector<int> > third; // empty stack using vector
std::stack<int,std::vector<int> > fourth (myvector);
2.16queue(キュー)
template <class T, class Container = deque<T> > class queue;
std::deque<int> mydeck (3,100); // deque with 3 elements
std::list<int> mylist (2,200); // list with 2 elements
std::queue<int> first; // empty queue
std::queue<int> second (mydeck); // queue initialized to copy of deque
std::queue<int,std::list<int> > third; // empty queue with list as underlying container
std::queue<int,std::list<int> > fourth (mylist);
2.17priority_queue(プライオリティキュー)
template <class T, class Container = vector<T>,
class Compare = less<typename Container::value_type> > class priority_queue;
#include <iostream> // std::cout
#include <queue> // std::priority_queue
#include <vector> // std::vector
#include <functional> // std::greater
class mycomparison
{
bool reverse;
public:
mycomparison(const bool& revparam=false)
{reverse=revparam;}
bool operator() (const int& lhs, const int&rhs) const
{
if (reverse) return (lhs>rhs);
else return (lhs<rhs);
}
};
int main ()
{
int myints[]= {10,60,50,20};
std::priority_queue<int> first;
std::priority_queue<int> second (myints,myints+4);
std::priority_queue<int, std::vector<int>, std::greater<int> >
third (myints,myints+4);
// using mycomparison:
typedef std::priority_queue<int,std::vector<int>,mycomparison> mypq_type;
mypq_type fourth; // less-than comparison
mypq_type fifth (mycomparison(true)); // greater-than comparison
return 0;
}
3. 容器の比較
3.2 連続コンテナ
名前 | 説明する | 特徴 | 方向 | イテレータが無効です | 入れる | 消去 | 探す | シーン |
---|---|---|---|---|---|---|---|---|
弦 | 文字列、シーケンス、ランダムアクセス | —— | 挿入は失敗するが、削除は失敗する | テール O(1) 非テール P: O(NP) | テール O(1) 非テール P: O(NP) | ○(1) | ベクトルと似ていますが、文字列から要素を削除してもスペースは解放されません(次の操作の便宜のため) | |
配列 | 配列、シーケンス | —— | 固定長 | なし | なし | ○(1) | ベクトルと同様に、配列よりも安全です(範囲外の心配はありません) が、内容はスタック上にあり、固定長のコンテナーに属します。 | |
ベクター | ベクトル、シーケンシャル、ランダム アクセス | 線形配列構造。配列と同等ですが、サイズは事前に指定されず、自動的に拡張されます。 ベクトルはメモリの連続したブロックです |
—— | 挿入と削除は失敗します | テール O(1) 非テール P: O(NP) |
テール O(1) 非テール P: O(NP) |
○(1) | 素早く検索する必要があるため、頻繁に挿入/削除する必要はありません |
したがって | キュー、シーケンス、ランダムアクセス | シーケンスの両端の要素を追加および削除するために最適化された基本的なシーケンス コンテナー。 デックはメモリの連続したブロックです。 |
双方向 | 挿入失敗。head 要素と tail 要素を削除すると、削除されたノードを指すイテレータが無効になり、中央の要素を削除するとすべてのイテレータが無効になります。 | 頭から尾まで: O(1) 頭から尾以外の P: O(min(p, NP)) |
頭から尾まで: O(1) 頭から尾以外の P: O(min(p, NP)) |
○(1) | 先頭から末尾までの要素の追加と削除は高速ですが、ヒープ ジャンプが内部で処理されるため、ランダム アクセスはベクターよりも少し遅くなります。中間の挿入と削除はより効率的です。リストとベクトルの組み合わせだからです。使い物にならない |
リスト | コンテナのリスト、順序 | 線形リンク リスト構造。そのデータは複数のノードで構成され、各ノードにはデータ、先行ポインタおよび後続ポインタが含まれます。 list には、すべてのデータ要素が個別に保存されます。 |
双方向 | 挿入しても無効になりません。削除されたノード自体が無効になります。 | ○(1) | ○(1) | の上) | 頻繁な挿入/削除が必要ですが、高速な検索は必要ありません |
forward_list | フォワードリスト、オーダー | 一方向 | 挿入しても無効になりません。削除されたノード自体が無効になります。 | ○(1) | ○(1) | の上) | リストの利点が必要ですが、前方に反復するだけです |
3.2 順序付けられた連想コンテナ
名前 | 説明する | 方向 | 特徴 | イテレータが無効です | 入れる | 消去 | 探す | シーン |
---|---|---|---|---|---|---|---|---|
地図 | マップ順序付き関連付け | 双方向 | リンクされたリスト | 挿入は失敗しません。削除すると削除したノードのイテレータのみが無効になりますが、イテレータは void を返すため、削除前にイテレータの位置を保存する必要があります。 | O(logN) | O(logN) | O(logN) | キーは値をキーに順番に関連付けるために必要であり、検索/削除/挿入のパフォーマンスは同じです |
マルチマップ | 複数のマッピングの順序付けられた関連付け | 双方向 | リンクされたリスト | 同上 | O(logN) | O(logN) | O(logN) | 同上 |
セット | 順序付けされた関連付けを設定する | 双方向 | リンクされたリスト | 同上 | O(logN) | O(logN) | O(logN) | 要素は順序付けする必要がありますが、検索/削除/挿入のパフォーマンスは同じです。赤黒木の効率は O(logN) です。たとえ何億のコンテンツがあっても、チェックされるのはせいぜい数十回です。 |
マルチセット | 複数セットの順序付き関連付け | 双方向 | リンクされたリスト | 同上 | O(logN) | O(logN) | O(logN) | 同上 |
3.3 順序付けされていない連想コンテナ
名前 | 説明する | 方向 | イテレータが無効です | 入れる | 消去 | 探す | シーン |
---|---|---|---|---|---|---|---|
順序なしマップ | 順序なし連想/ハッシュ テーブルのマッピング | 一方向 | 挿入と削除は無効です | 平均的なケース: O(1) 最悪のケース: O(N) | 平均的なケース: O(1) 最悪のケース: O(N) | 平均的なケース: O(1) 最悪のケース: O(N) | メモリ使用量は注文よりも高くなりますが、検索速度は速くなります。ハッシュ関数が悪すぎる場合、またはハッシュ再構築が発生した場合にのみ、O(N) に劣化します。しかし、それが起こることはめったになく、均等分布は依然として O(1) です。 |
unowned_multimap _ | マルチマップの順序付けされていない連想/ハッシュ テーブル | 一方向 | 同上 | 同上 | 同上 | 同上 | 同上 |
順序なしセット | 集合无序关联 | 单向 | 同上 | 同上 | 同上 | 同上 | 同上 |
unordered_multiset | 多重集合无序关联 | 单向 | 同上 | 同上 | 同上 | 同上 | 同上 |
3.4容器适配器
名称 | 说明 | 迭代器失效 | 插入 | 删除 | 查找 | 场景 |
---|---|---|---|---|---|---|
stack | 映射无序关联 | 不支持迭代器 | 只能尾端入:O(1) | 只能尾端删除:O(1) | 不支持 | FILO(先进后出)底层容器可以是list或vector或deque。 |
queue | 队列 | 不支持迭代器 | 只能尾端入:O(1) | 只能首端删除:O(1) | 不支持 | FIFO(先进先出)。底层容器可以是list或deque。 |
priority_queue | 优先、队列 | 不支持迭代器 | 同上 | 同上 | 不支持 | FIFO(先进先出)。底层容器可以是vector或deque。 |
3.5 小节
1、关联容器对元素的插入和删除操作比vector 要快,因为vector 是顺序存储,而关联容器是链式存储;
比list 要慢,是因为即使它们同是链式结构,但list 是线性的,而关联容器是二叉树结构,其改变一个元素涉及到其它元素的变动比list 要多,并且它是排序的,每次插入和删除都需要对元素重新排序;
2、 关联容器对元素的检索操作比vector 慢,但是比list 要快很多。
vector 是顺序的连续存储,当然是比不上的,但相对链式的list 要快很多是因为list 是逐个搜索,它搜索的时间是跟容器的大小成正比,而关联容器 查找的复杂度基本是Log(N) ,比如如果有1000 个记录,最多查找10 次,1,000,000 个记录,最多查找20 次。容器越大,关联容器相对list 的优越性就越能体现;
3、 在使用上set 区别于vector,deque,list 的最大特点就是set 是内部排序的,这在查询上虽然逊色于vector ,但是却大大的强于list 。
4、在使用上map 的功能是不可取代的,它保存了“键- 值”关系的数据,而这种键值关系采用了类数组的方式。数组是用数字类型的下标来索引元素的位置,而map 是用字符型关键字来索引元素的位置。在使用上map 也提供了一种类数组操作的方式,即它可以通过下标来检索数据,这是其他容器做不到的,当然也包括set 。
注意:STL 中只有vector 和map 可以通过类数组的方式操作元素,即如同num[1]下表索引的方式。
5、适配器是容器的接口,它本身不能直接保存元素,它保存元素的机制是调用另一种顺序容器去实现,即可以把适配器看作“它保存一个容器,这个容器再保存所有元素”。
STL 中提供的三种适配器可以由某一种顺序容器去实现。默认下stack 和queue 基于deque 容器实现,priority_queue 则基于vector 容器实现。
当然在创建一个适配器时也可以指定具体的实现容器,创建适配器时在第二个参数上指定具体的顺序容器可以覆盖适配器的默认实现。