STL容器之vector容器

STL-vector

Posted by Zhihao on 2020-11-20

The First Title Picture

基础

vector的数据结构和数组相似,也称为单端数组。

主要的特点(优势)在于可以动态扩展。

动态扩展并不是在原来的空间之后接新的空间,而是适当增加一定量的空间找一段新的内存去存储,然后将原来的数据拷贝过来并且释放原来的空间。

vector容器的迭代器是支持随机访问的迭代器,最牛的那种,迭代器可以随意加数值。

The First Title Picture

代码

Talk is cheap, show me the code.

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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
#include<iostream>
using namespace std;
#include<vector>

//打印函数的实现
void printVector(vector<int>& v)
{
for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
{
cout << *it << " ";
}
cout << endl;
}


/*
构造函数原型:
vector<T> v; //采用模板实现类实现,默认构造函数
vector(v.begin(), v.end()); //将v[begin(), end())区间中的元素拷贝给本身。
vector(n, elem); //构造函数将n个elem拷贝给本身。
vector(const vector &vec); //拷贝构造函数。
*/

void test01()
{
//默认构造函数实现
vector<int> v1;

for (int i = 0; i < 10; i++)
{
v1.push_back(i);
}

printVector(v1);

//区间
vector<int> v2(v1.begin(), v1.end());
printVector(v2);

//测试任意区间
//测试说明vector是支持随意访问的迭代器
vector<int> v3(v1.begin(), v1.begin() + 4);
printVector(v3);

vector<int> v4(10, 99);
printVector(v4);

vector<int> v5(v4);
printVector(v5);

}


/*
赋值函数原型:
vector& operator=(const vector &vec); //重载等号操作符
assign(beg, end); //将[beg, end)区间中的数据拷贝赋值给本身。
assign(n, elem); //将n个elem拷贝赋值给本身。
*/

void test02()
{
vector<int> v1;
for (int i = 10; i > 0; i--)
{
v1.push_back(i);
}
printVector(v1);

vector<int> v2;
v2 = v1;
printVector(v2);

vector<int> v3;
v3.assign(v2.begin(), v2.end());
printVector(v3);

vector<int> v4;
v4.assign(10, 88);
printVector(v4);

}


/*
容量和大小函数原型:
empty(); //判断容器是否为空
capacity(); //容器的容量
size(); //返回容器中元素的个数
resize(int num); //重新指定容器的长度为num,若容器变长,则以默认值填充新位置, 默认填充0。
//如果容器变短,则末尾超出容器长度的元素被删除。
resize(int num, elem); //重新指定容器的长度为num,若容器变长,则以elem值填充新位置(自己指定)。
//如果容器变短,则末尾超出容器长度的元素被删除
*/

void test03()
{
vector<int> v1;
for (int i = 0; i < 10; i++)
{
v1.push_back(i);
}

if (v1.empty())
{
cout << "v1 is empty" << endl;
}
else
{
cout << "the capacity of v1: " << v1.capacity() << endl;
cout << "the size of v1: " << v1.size() << endl;

}

v1.resize(20, 99);
printVector(v1);

v1.resize(5);
printVector(v1);
}




/*
插入和删除函数原型:
push_back(ele); //尾部插入元素ele
pop_back(); //删除最后一个元素
insert(const_iterator pos, ele); //迭代器指向位置pos插入元素ele
insert(const_iterator pos, int count,ele); //迭代器指向位置pos插入count个元素ele
erase(const_iterator pos); //删除迭代器指向的元素
erase(const_iterator start, const_iterator end); //删除迭代器从start到end之间的元素
clear(); //删除容器中所有元素
*/

void test04()
{
vector<int> v1;
for (int i = 0; i < 10; i++)
{
v1.push_back(i);
}
printVector(v1);

v1.pop_back();
printVector(v1);

//v1.insert(10, 9999); //必须是迭代器而不是随意的数字
v1.insert(v1.begin() + 9, 999);
printVector(v1);

v1.insert(v1.begin() + 10, 5, 888);
printVector(v1);

v1.erase(v1.end() - 1);
printVector(v1);

v1.erase(v1.begin(), v1.begin() + 5);
printVector(v1);

v1.clear();
if (v1.empty())
{
cout << "Now v1 is empty" << endl;
}

}


/*
数据存取函数原型:
at(int idx); //返回索引idx所指的数据
operator[]; //返回索引idx所指的数据
front(); //返回容器中第一个数据元素
back(); //返回容器中最后一个数据元素
*/

void test05()
{
vector<int> v1;
for (int i = 0; i < 10; i++)
{
v1.push_back(i);
}
cout << v1.at(1) << endl;
cout << v1[1] << endl;
cout << v1.front() << endl;
cout << v1.back() << endl;
}

/*
互换容器函数原型:
swap(vec); // 将vec与本身的元素互换
//本身并没有什么难度,主要是用来收缩内存空间
*/

void test06()
{
vector<int> v1;
for (int i = 0; i < 100000; i++)
{
v1.push_back(i);
}
cout << v1.capacity() << endl; //会预留较大的空间
cout << v1.size() << endl;

v1.resize(5);
cout << v1.capacity() << endl; //容量并不会减少
cout << v1.size() << endl;

vector<int>(v1).swap(v1);
cout << v1.capacity() << endl;
cout << v1.size() << endl;
//vector<int>(v) 匿名对象,它在内存中没有变量名,而且长度是v的实际长度,
//然后swap是一个指针的交换,这样自然而然实际刚才的v就变成了短的那个,
//匿名对象的一个特点,当前行执行完了,编译器发现他是匿名对象,就直接回收


}


/*
预留空间:减少vector在动态扩展容量时的扩展次数
函数原型:
reserve(int len); //容器预留len个元素长度,预留位置不初始化,元素不可访问。
*/

void test07()
{
vector<int> v1;
int m_count = 0; //统计动态扩展的次数
int* p = NULL;
for (int i = 0; i < 100000; i++)
{
v1.push_back(i);
if (p != &v1[0])
{
p = &v1[0];
m_count++;
}
}
cout << m_count << endl;

vector<int> v2;
v2.reserve(100000);
int m_count1 = 0;
int* p1 = NULL;
for (int i = 0; i < 100000; i++)
{
v2.push_back(i);
if (p1 != &v2[0])
{
p1 = &v2[0];
m_count1++;
}
}
cout << m_count1 << endl;

}


int main()
{
test07();
system("pause");
return 0;
}

...

...

00:00
00:00