文章目錄
API可訪問cplusplus.com/reference
4. deque容器
deque<int> d
可翻譯爲雙端隊列,主要操作與vector
類似:
push_back(),pop_back(),push_front(),pop_front()
front(),back()
取頭尾元素iterator find(iterator begin, iterator end, value)
根據值找索引,找不到則返回end()
5. stack容器
stack<int> s
主要操作:
void push(),void pop()
bool empty()
,常用語句爲while( !s.empty()){}
s.top()
獲取棧頂元素
可嘗試練習用棧等容器存儲指針
6. queue容器
queue<int> q
主要操作和棧相同。
6.1 priority_queue
the first element is always the greatest of the elements it contains.
template <class T, class Container = vector<T>,
class Compare = less<typename Container::value_type> >
/*
std::less
returns whether the its first argument compares less than the second
*/
默認最大優先級隊列.
#include<iostream>
using namespace std;
#include "queue"
#include "functional"
int main(int argc, char *argv[])
{
priority_queue<int> pq1;
//priority_queue<int,vector<int>,less<int> > pq2;
priority_queue<int,vector<int>,greater<int> > pq3;
pq1.push(5);
pq1.push(3);
pq1.push(7);
while(pq1.size())
{
cout<<pq1.top()<<" ";
pq1.pop();
}
cout<<endl;
pq3.push(5);
pq3.push(3);
pq3.push(7);
while(pq3.size())
{
cout<<pq3.top()<<" ";
pq3.pop();
}
cin.get();
return 0;
}
/*
7 5 3
3 5 7
*/
7. List容器
雙向鏈表容器,不能隨機存取元素,即不支持[]
和at()
;迭代器支持it++
,但不支持it+2
等隨機訪問。
一些操作可以查詢API
刪除
list.clear()
,清空
iterator list.erase(iterator begin, iterator end)
,注意左閉右開,返回後 一元素位置
iterator list.erase(iterator pos)
list.remove(elem)
刪除所以該值
#include<iostream>
using namespace std;
#include "list"
int main(int argc, char *argv[])
{
list<int> l;
l.push_back(1);
l.push_back(2);
l.push_back(3);
l.push_back(4);
list<int>::iterator it1 = l.begin();
list<int>::iterator it2 = l.begin();
//list<int>::iterator it2 = l.begin() + 3;
it2++;
it2++;
list<int>::iterator it3 = l.erase(it1,it2);
it1 = l.begin();
while(it1 != l.end())
{
cout<<*it1<<" ";
it1++;
}
cout<<endl;
cout<<*it3<<endl;
cin.get();
return 0;
}
/*
3 4
3
*/
8. Set和MultSet
集合採用紅黑樹這種平衡二叉樹數據結構實現,所以:
- 不能指定插入位置
- 不能直接存取(
[]
,at()
) - 不能直接修改元素,必須先刪除再重新添加
set
支持唯一鍵值對,而multiset
同一值可以出現多次。
集合自動排序,默認從小到大。
8.1 添加和刪除
#include<iostream>
using namespace std;
#include <set>
#include <functional>
int main(int argc, char *argv[])
{
set<int> set1;
set<int,greater<int> > set2;
for(int i = 0 ; i < 3; i++)
{
int tmp = rand()%100;
set1.insert(tmp);
set2.insert(tmp);
}
for(set<int>::iterator it = set1.begin(); it != set1.end(); it++)
{
cout<<*it<<" ";
}
cout<<endl;
for(set<int>::iterator it = set2.begin(); it != set2.end(); it++)
{
cout<<*it<<" ";
}
cout<<endl;
while( !set1.empty())
{
set1.erase(set1.begin());
}
while( !set2.empty())
{
set2.erase(set2.begin());
}
cin.get();
return 0;
}
/*
34 41 67
67 41 34
*/
對於自定義數據類型,應使用仿函數functor
和函數對象。
是使一個類的使用看上去象一個函數。其實現就是類中實現一個operator()
,這個類就有了類似函數的行爲。less<T>()
和greater<T>()
就是預定義的仿函數,包含在頭文件<functional>
中。
struct greater
{ // functor for operator>
typedef _Ty first_argument_type;
typedef _Ty second_argument_type;
typedef bool result_type;
constexpr bool operator()(const _Ty& _Left, const _Ty& _Right) const
{ // apply operator> to operands
return (_Left > _Right);
}
};
8.1.1 pair
當比較的值相等時,會插入失敗,所以我們要用對組pair
類型返回值判斷。
This class couples together a pair of values, which may be of different types (T1 and T2). The individual values can be accessed through its public members first and second.
set.insert()
return a pair, with its member pair::first
set to an iterator pointing to either the newly inserted element or to the equivalent element already in the set. The pair::second
element in the pair is set to true
if a new element was inserted or false
if an equivalent element already existed.
#include<iostream>
using namespace std;
#include "set"
#include "functional"
class Person
{
private:
int age;
public:
Person(int age)
{
this->age = age;
}
int getAge()const
{
return this->age;
}
};
struct greaterPerson {
bool operator() (const Person& left, const Person& right) const
{
return left.getAge() > right.getAge();
}
};
int main(int argc, char *argv[])
{
Person p1(11), p2(22), p3(33), p4(11);
set<Person, greaterPerson> set1;
Person *persons[4] = { &p1,&p2,&p3,&p4 };
pair<set<Person, greaterPerson>::iterator, bool> pair;
for (int i = 0; i < 4; i++)
{
pair = set1.insert(*persons[i]);
if (!pair.second)
{
printf("p%d inserted error.\n",i+1);
}
}
for(set<Person, greaterPerson>::iterator it = set1.begin(); it != set1.end(); it++)
{
cout << (*it).getAge() << endl;
}
cin.get();
return 0;
}
/*
p4 inserted error.
33
22
11
*/
8.2 查找
iterator set.find(elem)
,返回指向elem的迭代器,沒找到則返回set.end()
int set.count(elem)
,對於set
,返回0或1;對於multiset
,可能大於1.
iterator set.lower_bound(elem)
返回第一個大於等於elem的迭代器
iterator set.upper_bound(elem)
返回第一個大於elem的迭代器
pair<iterator,iterator> equal_range(elem)
,pair::first
is the lower bound of the range (the same as lower_bound
), and pair::second
is the upper bound (the same as upper_bound
). 相當於一個左閉右開區間。
9. Map和MultMap
map
是標準的關聯式容器,是一個key-value
對,也按紅黑樹規則排序,不能指定位置插入。
添加和刪除操作比vector
快。
支持[]
map
的鍵是唯一的;multimap
相同鍵可出現多次,所以不支持[]
。
map<T1,T2> m;
9.1 添加、刪除、遍歷
幾種常用的insert()
:
pair<iterator,bool> insert (const value_type& val);
iterator insert (const_iterator position, const value_type& val);
void insert (InputIterator first, InputIterator last);
#include<iostream>
using namespace std;
#include "map"
int main(int argc, char *argv[])
{
map<char,int> mymap;
mymap.insert ( pair<char,int>('a',100) );
mymap.insert ( make_pair<char,int>('b',100) );
pair<map<char,int>::iterator,bool> mypair = mymap.insert ( map<char,int>::value_type('c',100) );
cout<<"mypair.first:"<<mypair.first->second<<endl;
mymap['d'] = 100;
mymap['d'] = 200;
map<char,int>::iterator it = mymap.begin();
mymap.insert (it, std::pair<char,int>('e',300));
mypair = mymap.insert ( pair<char,int>('a',100) );
cout<<"mypair.second:"<<mypair.second<<endl;
map<char,int> anothermap;
anothermap.insert(mymap.begin(),mymap.find('e'));
for (it=anothermap.begin(); it!=anothermap.end(); ++it)
cout << it->first << " => " << it->second << '\n';
while(!mymap.empty())
{
map<char,int>::iterator it = mymap.begin();
mymap.erase(it);
}
while(!anothermap.empty())
{
map<char,int>::iterator it = anothermap.begin();
anothermap.erase(it);
}
cin.get();
return 0;
}
/*
mypair.first:100
mypair.second:0
a => 100
b => 100
c => 100
d => 200
*/
這裏注意一下隊組配合迭代器的用法:mypair.first->second;
9.2 查找
和[set的查找](#8.2 查找)類似。
iterator map.find(key);
map.count(key);
,結尾爲0或1;multimap
可以大於1.
10. 各個容器比較
每個容器都有默認的構造函數和默認拷貝構造函數。
除了queue
和stack
,每個容器都有可返回迭代器的函數。
大小相關函數:size(),empty()
vector | deque | list | set/multiset | map | multimap | |
---|---|---|---|---|---|---|
數據結構 | 單端數組 | 雙端數組 | 雙向鏈表 | 二叉樹 | 二叉樹 | 二叉樹 |
可隨機存取 | 1 | 1 | 0 | 0 | key可以 | 0 |
查找速度 | 慢 | 慢 | 很慢 | 快 | 慢 | key快 |
添加刪除 | 尾端 | 雙端 | 任何位置 | - | - | - |
deque
可用於排隊系統,而不是vector
.
vector
與deque
的比較:
at()
,vetor
比deque
快,因爲後者開頭位置不固定;- 大量釋放操作,
vector
更快; - 頭部的快速添加刪除是
deque
的優勢。
list
可用於乘客的存儲。
set
可用於存取個人得分。
map
可按id存儲用戶。
[#8.2 查找]: