C++的STL容器1

deque容器

deque容器基本概念
双端数组,可以对头端(尾端)进行插入删除操作

deque 与 vector区别
vector对于头部插入删除效率底,数据量越大,效率越低;vector 访问效率高
deque相对而言,对头部插入删除速度会比vector快
vector访问元素时的速度会比deque快,这和两者内部实现有关。

push_front、pop_front 插入和移除头部一个元素
push_back、pop_back 插入和移除尾部一个元素
insert 指定位插入
begin、end 迭代器

deque 内部工作原理
deque内部有个中控器,维护每段缓冲区中的内容,缓冲区中存放真实数据;中控器维护的是每个缓冲区的地址,使得使用deque时像一片连续的内存空间;当数据插满的时候,再找一段内存插入数据进去,再去中控器中记录这个地址
中控器中有很多的节点,指向数据的缓冲器。

deque容器的迭代器支持随机访问

deque构造函数

1
2
3
4
deque<T> qeqT;							//默认构造形式
deque(begin,end); //构造函数将[begin,end)区间中的元素拷贝给本身
deque(n,elem); //构造函数将n个elem拷贝给本身
deque(const deque &deq); //拷贝构造函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <iostream>
#include <deque>
#include <string>
using namespace std;

void printDeque(const string str,deque<int> &deq)
{
cout << str + ':' << endl;
for (deque<int>::const_iterator it = deq.begin(); it != deq.end(); it++)
{
cout << *it << '\t';
}
cout << endl;
}

void test01()
{
deque<int> deq;
for (size_t i = 0; i < 10; i++)
{
deq.push_back(i);
}
printDeque("deq",deq);

deque<int> d2(deq.begin(),deq.end()-5);
printDeque("d2",d2);

deque<int> d3(10, 100);
printDeque("d3", d3);

deque<int> d4(d3);
printDeque("d4", d4);
}

int main()
{
test01();
return 0;
}

const_iterator:只读迭代器
iterator:可读可写迭代器
deque容器和vector容器的构造方式几乎一样。

deque 容器赋值操作

1
2
3
deque & operator=(const deque &deq);			//重载等号操作符
assign(beg.end); //将[begin,end)区间中的数据拷贝给本身
assign(n,elem); //将n个elem拷贝赋值给本身
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <iostream>
#include <deque>
#include <string>
using namespace std;

void printDeque(const string str, deque<int> &deq)
{
cout << str + ':' << endl;
for (deque<int>::const_iterator it = deq.begin(); it != deq.end(); it++)
{
cout << *it << '\t';
}
cout << endl;
}

int main()
{
deque<int> d1;
for (size_t i = 0; i < 10; i++)
{
d1.push_back(i);
}
printDeque("d1",d1);

deque<int> d2 = d1;
printDeque("d2", d2);

deque<int> d3;
d3.assign(d2.begin(),d2.end());
printDeque("d3", d3);

deque<int> d4;
d4.assign(10, 100);
printDeque("d4", d4);
return 0;
}

deque大小操作

1
2
3
4
deque.empty();				//判断容器是否为空
deque.size(); //返回容器中的元素个数
deque.resize(num); //重新指定容器的长度为num,若容器变长,则以默认值填充新位置。如果容器变短,则末尾超出容器长度的元素被删除。
deque.resize(num,elem); //重新指定容器的长度为num,若容器变长,则以elem值填充新位置。如果容器变短,则末尾超出容器长度的元素被删除。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <iostream>
#include <deque>
#include <string>
using namespace std;

void printDeque(string str, const deque<int> &d)
{
cout << str + ':' << endl;
for (deque<int>::const_iterator it = d.begin(); it != d.end(); it++)
{
cout << *it << '\t';
}
cout << endl;
}

int main()
{
deque<int> d1;
for (size_t i = 0; i < 10; i++)
{
d1.push_back(i);
}
cout << "d1容器是否为空:" << (d1.empty() ? "是" : "否") << endl;
cout << "d1容器大小:" << d1.size() << endl;

d1.resize(30);//容器扩大使用默认值填充
cout << "d1容器大小:" << d1.size() << endl;
printDeque("28行", d1);

d1.resize(10);//容器变小
cout << "d1容器大小:" << d1.size() << endl;
printDeque("32行", d1);

d1.resize(20,5);//容器扩大使用指定的值填充
cout << "d1容器大小:" << d1.size() << endl;
printDeque("36行", d1);

return 0;
}

deque是没有容量概念,没有capacity;

deque容器插入和删除

两端插入操作:

1
2
3
4
push_back(elem);					//容器尾部添加一个元素
push_front(elem); //容器头部添加一个元素
pop_back(); //删除容器最后一个元素
pop_front(); //删除容器第一个元素

指定位置操作:

1
2
3
4
5
6
insert(pos,elem);					//在pos位置插入一个elem元素的拷贝,返回新数据的位置 (pos位置提供一个迭代器位置)
insert(pos,n,elem); //在pos位置插入n个elem元素,无返回值。
insert(pos,beg,end); //在pos位置插入[beg,end)区间的数据,无返回值。
clear(); //清空容器的所有数据
erase(beg,end); //删除[beg,end)区间的数据,返回下一个数据的位置
erase(pos); //删除pos位置的数据,返回下一个数据的位置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#include <iostream>
#include <deque>
#include <string>
using namespace std;

void printDeque(string str, const deque<int> &d)
{
cout << str + ':' << endl;
for (deque<int>::const_iterator it = d.begin(); it != d.end(); it++)
{
cout << *it << '\t';
}
cout << endl;
}

int main()
{
deque<int> d1;
d1.push_back(10);
d1.push_back(20);

d1.push_front(100);
d1.push_front(200);
printDeque("d1", d1);

d1.pop_back();
printDeque("d1", d1);
d1.pop_front();
printDeque("d1", d1);

d1.push_back(20);
d1.push_front(200);

d1.insert(d1.begin() + 1, 1000);
printDeque("d1", d1);

d1.insert(d1.begin() + 1, 2, 10000);
printDeque("d1", d1);

deque<int> d2;
d2.push_back(1);
d2.push_back(2);
d2.push_back(3);
//按照区间插入
d1.insert(d1.begin(),d2.begin(),d2.end()-1);
printDeque("d1", d1);

//删除
deque<int>::iterator it = d1.begin();
it++;
it = d1.erase(it);
printDeque("d1", d1);

d1.erase(it, it + 2);
printDeque("d1", d1);

d1.clear();
printDeque("d1", d1);
return 0;
}

总结:
插入和删除提供的位置是迭代器

deque数据存储

1
2
3
4
at(int idx);							//返回索引idx所指的数据
operator []; //返回索引idx所指的数据
front(); //返回容器中第一个数据元素
back(); //返回容器中最后一个数据元素
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <iostream>
#include <deque>
#include <string>
using namespace std;

int main()
{
deque<int> d1;

for (size_t i = 0; i < 10; i++)
{
d1.push_back(i);
}
for (size_t i = 0; i < 10; i++)
{
cout << d1.at(i) << '\t';
}
cout << endl;

d1[3] = 1000;
for (size_t i = 0; i < 10; i++)
{
cout << d1[i] << '\t';
}
cout << endl;

cout << "第一个元素:" << d1.front() << endl;
cout << "最后一个元素:" << d1.back() << endl;

return 0;
}

deque排序

利用算法实现deque容器进行排序

1
sort(iterator beg,iterator end);			//对beg和end区间元素进行排序(默认排序规则,从小到大 升序)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <iostream>
#include <deque>
#include <string>
#include <algorithm> //标准算法头文件
using namespace std;

void printDeque(const string str, deque<int> &deq)
{
cout << str + ':' << endl;
for (deque<int>::const_iterator it = deq.begin(); it != deq.end(); it++)
{
cout << *it << '\t';
}
cout << endl;
}

int main()
{
deque<int> d1;
d1.push_back(10);
d1.push_back(20);
d1.push_back(30);
d1.push_front(100);
d1.push_front(200);
d1.push_front(300);
printDeque("d1",d1);

sort(d1.begin(), d1.end());
printDeque("d1", d1);

return 0;
}

对于支持水机访问的迭代器的容器,都可以利用sort算法直接对其进行排序

stack容器

先进后出 push pop

stack常用接口

构造函数:

1
2
stack<T> stk;					//stack采用模板类实现,stack对象的默认构造形式
stack(const stack & stk); //拷贝构造函数

赋值操作:

1
stack & operator=(const stack &stk);			//重载等号操作符

数据存储

1
2
3
push(elem);					//向栈顶添加元素
pop(); //从栈顶一处第一元素
top(); //返回栈顶元素

大小操作:

1
2
empty();					//判断堆栈是否为空
size(); //返回栈的大小
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <iostream>
#include <stack>
using namespace std;

int main()
{
stack<int> s;
s.push(10);
s.push(20);
s.push(30);
s.push(40);

stack<int> s1(s);

while (!s.empty())
{
cout << "栈顶元素:" << s.top() << endl;
s.pop();
}

cout << "栈大小:" << s.size() << endl;

s = s1;

while (!s.empty())
{
cout << "s栈顶元素:" << s.top() << endl;
s.pop();
}

while (!s1.empty())
{
cout << "s1栈顶元素:" << s1.top() << endl;
s1.pop();
}

}

queue容器

是一种先进先出(First In First Out,FIFO)的数据结构,它有两个出口

队尾只能插入数据(push);队头只能取数据(pop) ;队尾back();队头front();队头队尾看个人指定

队列容器允许从一端新增元素,从另一端移除元素
队列中只有队头和队尾才可以被外界使用,因此队列不允许有遍历行为;

构造函数:

1
2
queue<T> stk;					//queue采用模板类实现,queue对象的默认构造形式
queue(const queue & stk); //拷贝构造函数

赋值操作:

1
queue & operator=(const queue &stk);			//重载等号操作符

数据存储

1
2
3
4
push(elem);					//向队尾添加元素
pop(); //从队头移除第一元素
front(); //返回第一个元素
back(); //返回最后一个元素

大小操作:

1
2
empty();					//判断队列是否为空
size(); //返回队列的大小
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#include <iostream>
#include <queue>
#include <string>
using namespace std;

class Person
{
public:
Person(string name, int age) :m_name(name), m_age(age)
{

}
~Person();

string readname(void)
{
return this->m_name;
}

int readage(void)
{
return this->m_age;
}

private:
string m_name;
int m_age;
};


Person::~Person()
{
}

int main()
{
queue<Person> q;

//准备数据
Person p1("唐僧",30);
Person p2("孙悟空", 1000);
Person p3("猪八戒", 900);
Person p4("沙僧", 800);

//入队
q.push(p1);
q.push(p2);
q.push(p3);
q.push(p4);

cout << "容量" << q.size() << endl;

//判断只要队列不为空,查看队头,查看队尾,出队
while (!q.empty())
{
//查看队头
cout << "队头元素 ----- 姓名" << q.front().readname() << " 年龄:" << q.front().readage() << endl;

//查看队尾
cout << "队尾元素 ----- 姓名" << q.back().readname() << " 年龄:" << q.back().readage() << endl;

//出队
q.pop();
}

cout << "容量" << q.size() << endl;
}

list容器

STL中的链表是一个双向循环链表
push_front、push_back、pop_front、pop_back、insert、begin、end

list构造函数

1
2
3
4
list<T> lst;						//list采用模板类实现,对象的默认构造形式
list(begin,end); //构造函数将[begin,end)区间中的元素拷贝给本身
list(n,elem); //构造函数将n个elem拷贝给本身
list(const list & lst); //拷贝构造函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <iostream>
#include <list>
using namespace std;

void printList(const list<int> &lst)
{
for (list<int>::const_iterator it = lst.begin(); it != lst.end(); it++)
{
cout << *it << '\t';
}
cout << endl;
}

int main()
{
list<int> lst;

lst.push_back(10);
lst.push_back(20);
lst.push_back(30);
lst.push_back(40);

printList(lst);

list<int>::iterator it = lst.begin();
it++;
it++;
list<int> lst2(it, lst.end()); //构造部分区间
printList(lst2); //

list<int> lst3(lst);
printList(lst3); //

list<int> lst4(10,1000);
printList(lst4); //

return 0;
}

list赋值和交换