当前位置:   article > 正文

C++ vector容器_vector>

vector>

一、vector的介绍

  1. vector是表示可变大小数组的序列容器。
  2. 它和数组一样,也是采用连续存储空间存储元素,所以同样也可以采用下标对vector的元素进行访问,但是它的大小是动态改变的,也就是说它如果不够用,它会自动增容。
  3. 本质讲,vector使用动态分配数组来存储它的元素。当新元素插入时候,这个数组需要被重新分配大小,重新分配一个新的数组,然后将全部元素移到这个数组。

  4. vector分配空间策略:vector会分配一些额外的空间以适应可能的增长,因为存储空间比实际需要的存储空间更大。

  5.  vector占用了更多的存储空间,为了获得管理存储空间的能力,并且以一种有效的方式动态增 长。

  6. 与其它动态序列容器相比, vector在访问元素的时候更加高效,在末尾添加和删除元素相对高效。

二、vector的使用

1、vector的定义

vector() 
无参构造
vector(size_t n, const value_type&val=value_type())
构造并初始化nval
vector (const vector& x); 拷贝构造
vector (InputIterator fifirst, InputIterator last); 使用迭代器进行初始化构造
  1. #include<iostream>
  2. #include<vector>
  3. using namespace std;
  4. int main()
  5. {
  6. vector<int> v(10); //一个参数
  7. cout << v.size() << endl;
  8. vector<int> v1(10, 6); //n个val值
  9. for (auto &i : v1)
  10. {
  11. cout << i;
  12. }
  13. cout << endl;
  14. vector<int> v2 = v1;//拷贝
  15. for (auto &i : v2)
  16. {
  17. cout << i;
  18. }
  19. cout << endl;
  20. vector<int>v3(v1.begin() + 3, v1.end() - 2);//迭代器方法
  21. for (auto &i : v3)
  22. {
  23. cout << i;
  24. }
  25. cout << endl;
  26. system("pause");
  27. return 0;
  28. }

2、vector iterator的使用

begin + end
获取第一个数据位置的iterator,获取最后一个数据的下一个位置的iterator
rbegin + rend
获取最后一个数据位置的reverse_iterator,获取第一个数据前一个位置 reverse_iterator

 

  1. int main()
  2. {
  3. vector<int> v4;
  4. for (int i = 1; i <= 10; i++)
  5. {
  6. v4.push_back(i);
  7. }
  8. vector<int>::iterator fi;
  9. vector<int>::reverse_iterator ri;
  10. for (fi = v4.begin(); fi != v4.end(); fi++)
  11. {
  12. cout << *fi << ' ';
  13. }
  14. cout << endl;
  15. for (ri = v4.rbegin(); ri != v4.rend(); ri++)
  16. {
  17. cout << *ri << ' ';
  18. }
  19. system("pause");
  20. return 0;
  21. }

3、vector空间增长问题

size数据的个数
capacity容量大小
empty判断是否为空
resize改变vector的size
reserve改变capacity

注:

vs下capacity是按1.5倍增加的,在g++下是按2倍增加的

reserve只负责开辟空间

resize在进行开空间的同时还会进行初始化 

首先,我们先看一下 capacity的变化

  1. #include<iostream>
  2. #include<vector>
  3. using namespace std;
  4. int main()
  5. {
  6. vector<int> v;
  7. size_t Capacity = v.capacity();
  8. for (int i = 0; i < 50; i++)
  9. {
  10. v.push_back(i);
  11. if (Capacity != v.capacity())
  12. {
  13. Capacity = v.capacity();
  14. cout << i << " capacity :" << Capacity << endl;
  15. }
  16. }
  17. system("pause");
  18. return 0;
  19. }

这个是在vs下进行的,可以清楚的看到是以1.5倍增加的 

resize的用法

  1. #include<iostream>
  2. #include<vector>
  3. using namespace std;
  4. int main()
  5. {
  6. vector <int> s;
  7. cout << s.size() << endl;
  8. for (int i = 0; i < 50; i++)
  9. {
  10. s.push_back(i);
  11. }
  12. cout << s.size() << endl;
  13. s.resize(5); //将size置为5
  14. cout << s.size() << endl;
  15. s.resize(8, 10);//将size置位8,多余位置用10来填充
  16. cout << s.size() << endl;
  17. s.resize(12);//将si'ze置为12,多余位置用0来填充
  18. cout << s.size() << endl;
  19. for (int i = 0; i < s.size(); i++)
  20. {
  21. cout << s[i] << ' ';
  22. }
  23. system("pause");
  24. return 0;
  25. }

 

从上边的代码以及结果来看 resize()的作用是改变vector中元素的数目。

resize可以有两个参数,第一个是要改变的大小,第二个是扩展的多余空间填充的数字。

如果第一个参数比当前的vector元素数目要小,vector的容量要缩减到resize的第一个参数大小并移除超出第一个参数大小的元素同时销毁他们。

如果第一个参数比当前vector元素数目要大,在vector的末尾扩展需要的元素数目,如果第二个参数指定了,扩展的新元素初始化为第二个指定的元素,否则按类型默认初始化。
 

reserve的使用

  1. #include<iostream>
  2. #include<vector>
  3. using namespace std;
  4. int main()
  5. {
  6. vector <int> s;
  7. cout << " capacity :" << s.capacity() << endl;
  8. for (int i = 0; i < 50; i++)
  9. {
  10. s.push_back(i);
  11. }
  12. cout << " capacity :" << s.capacity() << endl;
  13. s.reserve(100);
  14. cout << " capacity :" << s.capacity() << endl;
  15. system("pause");
  16. return 0;
  17. }

4、vector的增删改查

push_back 尾插
pop_back尾删
find查找,这个是算法模块的实现,不是vector的成员接口
insert在position之前插入val
erase删除position位置的数据
swap交换两个vector的数据空间
operator[]像数组一样访问

 

push_back、pop_back的用法

  1. #include<iostream>
  2. #include<vector>
  3. using namespace std;
  4. int main()
  5. {
  6. vector<int> v;
  7. for (int i = 0; i <= 10; i++)
  8. {
  9. v.push_back(i);
  10. }
  11. for (auto & i : v)
  12. {
  13. cout << i << ' ';
  14. }
  15. cout << endl;
  16. v.pop_back();
  17. v.pop_back();
  18. for (auto & i : v)
  19. {
  20. cout << i << ' ';
  21. }
  22. system("pause");
  23. return 0;
  24. }

find、insert、erase的用法 

  1. #include<iostream>
  2. #include<vector>
  3. using namespace std;
  4. int main()
  5. {
  6. vector<int> v;
  7. for (int i = 0; i <= 5; i++)
  8. {
  9. v.push_back(i);
  10. }
  11. for (auto & i : v)
  12. {
  13. cout << i << ' ';
  14. }
  15. cout << endl;
  16. vector<int>::iterator pos = find(v.begin(), v.end(), 3);
  17. //使用find查找3所在的位置
  18. v.insert(pos,30);//在pos位置前插入30
  19. for (auto & i : v)
  20. {
  21. cout << i << ' ';
  22. }
  23. cout << endl;
  24. pos = find(v.begin(), v.end(), 3);
  25. v.erase(pos);//删除pos所在位置的数据
  26. for (auto & i : v)
  27. {
  28. cout << i << ' ';
  29. }
  30. cout << endl;
  31. system("pause");
  32. return 0;
  33. }

swap、operator[]的用法 

  1. #include<iostream>
  2. #include<vector>
  3. using namespace std;
  4. int main()
  5. {
  6. int a[] = { 1, 2, 3, 4, 5 };
  7. vector<int> v(a, a + sizeof(a) / sizeof(int));
  8. v[0] = 10;//通过[]来读写第0个位置
  9. cout << v[0] << endl;
  10. for (int i = 0; i < v.size(); i++)
  11. {
  12. cout << v[i] << ' '; //通过[i]的方式遍历vector
  13. }
  14. cout << endl;
  15. vector<int> tmp;
  16. tmp.swap(v);
  17. cout << "v的内容 :";
  18. for (int i = 0; i < v.size(); i++)
  19. {
  20. cout << v[i] << ' ';
  21. }
  22. cout << endl;
  23. cout << "tmp的内容 :";
  24. for (int i = 0; i < tmp.size(); i++)
  25. {
  26. cout << tmp[i] << ' ';
  27. }
  28. cout << endl;
  29. system("pause");
  30. return 0;
  31. }

 

三、迭代器失效的问题

  1. #include<iostream>
  2. #include<vector>
  3. #include<algorithm>
  4. using namespace std;
  5. int main()
  6. {
  7. vector<int> v;
  8. for (int i = 0; i <= 5; i++)
  9. {
  10. v.push_back(i);
  11. }
  12. vector<int>::iterator pos = find(v.begin(), v.end(), 3);
  13. v.erase(pos); //删除pos位置的数据,导致pos迭代器失效
  14. cout << *pos << endl; //这样会导致非法访问
  15. vector<int>::iterator pos1 = find(v.begin(), v.end(), 3);
  16. v.insert(pos1,30); //在pos1位置前插入数据,导致pos1迭代器失效
  17. //insert会导致迭代器失效,是因为insert可能会导致增容,增容后pos1还指向原来的空间,而原来的空间已经被释放了
  18. cout << *pos1 << endl; //这样会导致非法访问
  19. system("pause");
  20. return 0;
  21. }

 

四、模拟实现vector

  1. namespace Jiang
  2. {
  3. template <class T>
  4. class vector
  5. {
  6. T * m_start;
  7. T * m_finish;
  8. T * m_endOfStorage;
  9. public:
  10. typedef T * iterator;
  11. typedef const T * const_iterator;
  12. vector() :
  13. m_start(nullptr),
  14. m_finish(nullptr),
  15. m_endOfStorage(nullptr)
  16. {
  17. }
  18. vector(int n, const T &val = T()) :
  19. m_start(nullptr),
  20. m_finish(nullptr),
  21. m_endOfStorage(nullptr)
  22. {
  23. reserve(n);
  24. for (int i = 0; i < n; i++)
  25. {
  26. m_start[i] = val;
  27. }
  28. m_finish = m_start + n;
  29. }
  30. vector(T * start, T * end) :
  31. m_start(nullptr),
  32. m_finish(nullptr),
  33. m_endOfStorage(nullptr)
  34. {
  35. int _size = end - start;
  36. reserve(_size);
  37. for (int i = 0; i < _size; i++)
  38. {
  39. m_start[i] = start[i];
  40. }
  41. m_finish = m_start + _size;
  42. }
  43. iterator begin()
  44. {
  45. return m_start;
  46. }
  47. iterator end()
  48. {
  49. return m_finish;
  50. }
  51. size_t size()
  52. {
  53. return m_finish - m_start;
  54. }
  55. size_t capacity()
  56. {
  57. return m_endOfStorage - m_start;
  58. }
  59. T & operator [] (int i)
  60. {
  61. return m_start[i];
  62. }
  63. const T & operator [] (int i) const
  64. {
  65. return m_start[i];
  66. }
  67. void reserve(size_t _size)
  68. {
  69. int _capacity = capacity();
  70. if (_capacity < _size)
  71. {
  72. if (_capacity == 0)
  73. {
  74. _capacity = 1;
  75. }
  76. while (_capacity < _size)
  77. {
  78. _capacity *= 2;
  79. }
  80. }
  81. T * tmp = new T[_capacity];
  82. m_endOfStorage = tmp + _capacity;
  83. int oldsize = size();
  84. m_finish = tmp + oldsize;
  85. if (m_start != nullptr)
  86. {
  87. for (int i = 0; i < oldsize; i++)
  88. {
  89. tmp[i] = m_start[i];
  90. }
  91. delete[] m_start;
  92. }
  93. m_start = tmp;
  94. }
  95. void resize(size_t _size, const T &val = T())
  96. {
  97. reserve(_size);
  98. for (int i = size(); i < _size; i++)
  99. {
  100. m_start[i] = val;
  101. }
  102. m_finish = m_start + _size;
  103. }
  104. iterator insert(iterator pos, const T &val)//insert防止迭代器失效,返回的是一个迭代器
  105. {
  106. int tmp = pos - m_start;
  107. reserve(size() + 1);
  108. pos = m_start + tmp;
  109. int i;
  110. for (i = size() - 1; i >= pos - m_start; i--)
  111. {
  112. m_start[i + 1] = m_start[i];
  113. }
  114. *pos = val;
  115. m_finish++;
  116. return pos;
  117. }
  118. iterator insert(iterator pos, int n, const T &val)
  119. {
  120. int tmp = pos - m_start;
  121. reserve(size() + n);
  122. pos = m_start + tmp;
  123. int i;
  124. for (i = size()- 1; i >= pos - m_start; i--)
  125. {
  126. m_start[i + n] = m_start[i];
  127. }
  128. for (i = 0; i < n; i++)
  129. {
  130. pos[i] = val;
  131. }
  132. m_finish += n;
  133. return pos;
  134. }
  135. iterator insert(iterator pos, const T * start, const T * end)//前置const 不能改内容, 后置const(T * const end)不能改指向
  136. {
  137. int tmp = pos - m_start;
  138. int extsize = end - start;
  139. reserve(size() + extsize);
  140. pos = m_start + tmp;
  141. int i;
  142. for (i = size() - 1; i >= pos - m_start; i--)
  143. {
  144. m_start[i + extsize] = m_start[i];
  145. }
  146. for (i = 0; i < extsize; i++)
  147. {
  148. pos[i] = start[i];
  149. }
  150. m_finish += extsize;
  151. return pos;
  152. }
  153. iterator erase(iterator pos)
  154. {
  155. int i;
  156. for (i = pos - m_start; i < size() - 1; i++)
  157. {
  158. m_start[i] = m_start[i + 1];
  159. }
  160. m_finish--;
  161. return pos;
  162. }
  163. iterator erase(iterator start, iterator end)
  164. {
  165. int i;
  166. int extsize = end - start;
  167. for (i = start - m_start; i < size() - extsize; i++)
  168. {
  169. m_start[i] = m_start[i + extsize];
  170. }
  171. m_finish -= extsize;
  172. return start;
  173. }
  174. void push_back(const T &val)
  175. {
  176. reserve(size() + 1);
  177. *m_finish = val;
  178. m_finish++;
  179. }
  180. void pop_back()
  181. {
  182. m_finish--;
  183. }
  184. };
  185. };

简单测试一下我们自己模拟出来的vector的某些函数

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/108469
推荐阅读
相关标签
  

闽ICP备14008679号