1.通用容器
(1)vector容器
(2)deque容器
(3)list容器
(4)队列和堆栈
(5)优先队列
(6)bitset容器
(7)集合
(8)映射
(9)再论迭代器
1.1容器分类
(1)序列性容器:按照线性排列来存储某类型值的集合,每个元素都有自己特有的位置,顺序容器主要有vector、deque、list。
(2)关联式容器:与前面讲到的顺序容器相比,关联容器更注重快速和高效地检索数据的能力。这些容器是根据键值(key)来检索数据的,键可以是值也可以是容器中的某一成员。这一类中的成员在初始化后都是按一定顺序排好序的。关联式容器主要有set、multiset、map、multimap。
(3)容器适配器:对已有的容器进行某些特性的再封装,不是一个真正的新容器。主要有stack、queue。
1.2容器共性
容器一般来说都有下列函数。
默认构造函数 提供容器默认初始化的构造函数。
复制构造函数 将容器初始化为现有同类容器副本的构造函数
析构函数 不再需要容器时进行内存整理的析构函数
empty 容器中没有元素时返回true,否则返回false
max_size 返回容器中最大元素个数
size 返回容器中当前元素个数
operator= 将一个容器赋给另一个容器
operator< 如果第一个容器小于第二个容器,返回true,否则返回false,
operator<= 如果第一个容器小于或等于第二个容器,返回true,否则返回false
operator> 如果第一个容器大于第二个容器,返回true,否则返回false
operator>= 如果第一个容器大于或等于第二个容器,返回true,否则返回false
operator== 如果第一个容器等于第二个容器,返回true,否则返回false
operator!= 如果第一个容器不等于第二个容器,返回true,否则返回false
swap 交换两个容器的元素
顺序容器和关联容器共有函数如下所示。
begin 该函数两个版本返回iterator或const_iterator,引用容器 第一个元素
end 该函数两个版本返回iterator或const_iterator,引用容器最后一个元素后面一位
rbegin 该函数两个版本返回reverse_iterator或const_reverse_iterator,引用容器最后一个元素
rend 该函数两个版本返回reverse_iterator或const_reverse_iterator,引用容器首个元素前面一位
erase 从容器中清除一个或几个元素
clear 清除容器中所有元素
1.3容器比较
vector(连续的空间存储,可以使用[]操作符)快速的访问随机的元素,快速的在末尾插
元素,但是在序列中间岁间的插入,删除元素要慢,而且如果一开始分配的空间不够
话,有一个重新分配更大空间,然后拷贝的性能开销。
deque(小片的连续,小片间用链表相连,实际上内部有一个map的指针,因为知道
型,所以还是可以使用[],只是速度没有vector快)快速的访问随机的元素,快速的在
始和末尾插入元素,随机的插入,删除元素要慢,空间的重新分配要比vector快,重新
配空间后,原有的元素不需要拷贝。对deque的排序操作,可将deque先复制到vector
排序后在复制回deque.
list(每个元素间用链表相连)访问随机元素不如vector快,随机的插入元素比vector快,对每个元素分配空间,所
不存在空间不够,重新分配的情况。
set 内部元素唯一,用一棵平衡树结构来存储,因此遍历的时候就排序了,查找也比较快。
map 一对一的映射的结合,key不能重复。
1.4vector容器
vector类称做向量类,它实现了动态的数组,用于元素数量变化的对象数组。象数组一样,vector类也用从0开
的下标表示元素的位置;但和数组不同的是,当vector对象创建后,数组的元素个数会随着vector对象元素个数
增大和缩小而自动变化。
常用函数
(1)构造函数
vector();创建一个空vector
vector(int nSize) ;创建一个vector,元素个数为nSize
vector(int nSize, const T& t);创建一个vector,元素个数为nSize,且值均为t
vector(const vector&);拷贝构造函数
(2)增加函数
void push_back(const T& x);向量尾部增加一个元素x
iterator insert(iterator it, const T& x);向量中某一元素前增加一个元素x
void insert(iterator it, int n, const T& x);向量中某一元素前增加n个相同元素x
void insert(iterator it,const_iterator first, const_iterator last);向量中某一元素前插入另一个相同类型向量的[first,last)]间的数据
(3)删除函数
iterator erase(iterator it);;删除向量中某一个元素
iterator erase(iterator first, iterator last);删除向量中[first,last)中元素
void pop_back();;删除向量中最后一个元素
void clear();;删除向量中所有元素
(4)遍历函数
reference at(int pos);返回pos位置元素的引用
reference front();返回首元素的引用
reference back();返回尾元素的引用
iterator begin();返回向量头指针,指向第一个元素
iterator end();返回向量尾指针,不包括最后一个元素,在其下面
reverse_iterator rbegin();反向迭代器,功能等同iterator end()
reverse_iterator rend();反向迭代器,功能等同iterator begin()
(5)判断函数
bool empty() const;向量是否为空?若true,则向量中无元素。
(6)大小函数
int size() const;返回向量中元素的个数
int capacity() const;返回当前向量所能容纳的最大元素值
int max_size() const;返回最大可允许的vector元素数量值
(7)其它函数
void swap(vector&);交换两个同类型向量的数据
void assign(int n, const T& x);向量中第n个元素设置成元素x
void assign(const_iterator first, const_iterator last);向量中[first,last]元素设置成向量元素
向量初始化举例
<span style="font-size:18px;">#include <vector>
#include <iostream>
class A //无特殊含义,仅是为了配合说明问题
{
};
int main(int argc, char* argv[])
{
std::vector<int> int_ect;
std::vector<float> flo_vect;
std::vector<A> cA_vect;
std::vector<A *> cpA_vect;
cout<<"init success!"<<endl;
return 0;
}</span><span style="font-size: 21px;">
</span>
删除,添加元素示例
<span style="font-size:18px;">#include<iostream>
#include<iterator>
#include<vector>
using namespace std;
int main()
{
vector<int>a;
for(int i=0;i<4;i++)
{
a.push_back(i+1);
}
a.push_back(5);
for(int i=0;i<a.size();i++)
{
cout<<a.at(i)<<" ";
}
cout<<endl;
a.erase(a.begin());
for(int i=0;i<a.size();i++)
{
cout<<a[i]<<" ";
}
cout<<endl;
a.erase(a.begin(),a.end()-2);
vector<int>::iterator int_value=a.begin();
while(int_value !=a.end())
{
cout<<*int_value++<<" ";
}
return 0;
}</span>
总之,增加新元素时,如果超过当前的容量,则容量会自动扩充2倍,如果两倍容量仍不足,就扩大至足够大的容量。本图是直接在原空间基础上画的新增空间,其实要复杂得多,包括重新配置、元素移动、释放原始空间的过程。因此对vector容器而言当增加新的元素时,有可能很快完成(直接存在预留空间中),有可能稍慢(扩容后再放新元素);对修改元素值而言是较快的;对删除元素来说,若删除尾部元素较快,非尾部元素则稍慢,因为牵涉到删除后的元素移动。
示例:
#include<vector>
#include<iostream>
using namespace std;
class A
{
private:
int n;
public:
A(int x=0):n(x)
{
}
int GetN()
{
return n;
}
};
int main()
{
cout<<"类A的向量操作"<<endl;
vector<A>a;
A a1(1);
A a2(2);
A a3(3);
a.push_back(a1);
a.push_back(a2);
a.push_back(a3);
int n=a.size();
cout<<"通过数组输出:"<<endl;
for(int i=0;i<n;i++)
{
cout<<a[i].GetN()<<"\t";
}
cout<<endl;
cout<<"通过引用输出:"<<endl;
for(int i=0;i<n;i++)
{
A &b=a.at(i);
cout<<b.GetN()<<"\t";
}
cout<<endl;
cout<<"通过迭代器输出:"<<endl;
vector<A>::iterator c=a.begin();
while(c!=a.end())
{
cout<<(*c++).GetN()<<"\t";
}
cout<<endl;
cout<<"类A的指针向量操作"<<endl;
vector<A*>vec_a;
A *a4=new A(4);
A *a5=new A(5);
A *a6=new A(6);
vec_a.push_back(a4);
vec_a.push_back(a5);
vec_a.push_back(a6);
int Size=vec_a.size();
cout<<"通过数组输出:"<<endl;
for(int i=0;i<Size;i++)
{
cout<<vec_a[i]->GetN()<<"\t";
}
cout<<endl;
cout<<"通过引用输出:"<<endl;
for(int i=0;i<Size;i++)
{
A *&p=vec_a.at(i);
cout<<p->GetN()<<"\t";
}
cout<<endl;
cout<<"通过迭代器输出:"<<endl;
vector<A*>::iterator p1=vec_a.begin();
while(p1!=vec_a.end())
{
cout<<(**p1++).GetN()<<"\t";
}
cout<<endl;
return 0;
}
#include<iostream>
#include<vector>
#include<string>
using namespace std;
class student
{
public:
string number;
string name;
string sex;
student(string num,string nam,string Sex):number(num),name(nam),sex(Sex){}
void display()
{
cout<<number<<"\t"<<name<<"\t"<<sex<<endl;
}
};
class StudentCollect
{
vector<student>stu;
public:
void add(student &s)
{
stu.push_back(s);
}
student *Find(string num)
{
int i;
for(i=0;i<stu.size();i++)
{
if(stu.at(i).number==num)
{
return &stu.at(i);
}
}
if(i==stu.size())
{
return NULL;
}
}
};
int main()
{
student s1("1001","张三","boy");
student s2("1002","张四","boy");
student s3("1003","张五","boy");
StudentCollect s;
s.add(s1);
s.add(s2);
s.add(s3);
student *ps=s.Find("1002");
if(ps)
{
ps->display();
}
return 0;
}
#include<iostream>
#include<vector>
#include<string>
using namespace std;
class Book
{
public:
string number;
string name;
Book(string num,string nam):number(num),name(nam){}
void showbook()
{
cout<<number<<"\t"<<name<<endl;
}
};
class writer
{
public:
string write_number;
string write_name;
vector<Book>book;
writer(string num,string nam):write_number(num),write_name(nam){}
void add(Book &book1)
{
book.push_back(book1);
}
void showwriter()
{
for(int i=0;i<book.size();i++)
{
cout<<write_number<<"\t"<<write_name<<"\t";
book[i].showbook();
}
}
void DeleteBook(string number)
{
int i;
for(i=0;i<book.size();i++)
{
if(book.at(i).number==number)
{
break;
}
}
if(i!=book.size())
{
book.erase(book.begin()+i);
}
}
};
class WriteCollect
{
public:
vector<writer>w;
void addwriter(writer &wr)
{
w.push_back(wr);
}
void display()
{
for(int i=0;i<w.size();i++)
{
w[i].showwriter();
}
}
void Delete(string number)
{
int i;
for(i=0;i<w.size();i++)
{
if(w[i].write_number==number)
{
break;
}
}
if(i!=w.size())
{
w.erase(w.begin()+i);
}
}
void writer_of_book(int i,string number)
{
w[i-1].DeleteBook(number);
}
};
int main()
{
writer w1("1001","张三");
Book b1("b001","aaa");
Book b2("b002","bbb");
w1.add(b1);
w1.add(b2);
writer w2("1002","张四");
Book b3("b003","ccc");
w2.add(b3);
WriteCollect collect;
collect.addwriter(w1);
collect.addwriter(w2);
collect.display();
collect.Delete("1002");
cout<<endl;
collect.display();
// collect.w[0].DeleteBook("b002");
collect.writer_of_book(1,"b002");
cout<<endl;
collect.display();
return 0;
}
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<vector<int> >v(2);
for (int i=0; i<2; i++)
{
v[i].resize(3); //<span style="color: rgb(51, 51, 51); font-family: Arial; line-height: 26px;"><span style="font-size:10px;">设置数组的大小2X3 </span></span>
}
for (int i=0; i<2; i++)
{
for (int j=0; j<3; j++)
{
v[i][j]=i*j;
cout<<v[i][j]<<" ";
}
cout<<endl;
}
}