STL_Vector
来源:互联网 发布:gta5ol捏脸美女数据 编辑:程序博客网 时间:2024/05/16 06:29
一、Vector简介
Vector是表示可以改变大小的数组的序列容器。 就像数组一样,Vector为它们的元素使用连续的存储位置,这意味着它们的元素也可以使用对其元素的常规指针的偏移来访问,并且与数组一样有效。 但是与数组不同的是,它们的大小可以动态地改变,其存储由容器自动处理。
二、Vector优缺点
缺点:
在内部,Vector使用动态分配的数组来存储它们的元素。既然是数组,最大的缺点就是在插入新元素时,插入位置之后的所有元素都得向后移动一个位置,效率就很低。
专门翻出了SGI STL中对Vector的实现:从下图里面我们就能看出其实Vector底层实现就像是一个动态的数组。
优点:
在进行push_back操作时,不需要像链表那样频繁的进行申请空间的操作,在前一次多余开辟空间未用完时,只需要进行一次赋值操作,再将finish向后指向一个元素。从SGI STL的扩容实现中就可以看出,第一次申请1个空间,之后每次都是二倍增长。(具体实现要看对应的编译器)
三、Vector接口使用
模板参数
修改编辑容器相关的接口:
关于容量相关的接口:
关于迭代器的接口:
接下来就来简单展示一些常用的接口使用方法(编译环境为VS2015)
例一(关于增容问题):
void Test1(){ vector<int> v1;//定义一个数据类型为int的vector v1.push_back(1); cout << v1.capacity() << endl; //输出:1 cout << v1.size() << endl; //输出:1 v1.push_back(2); cout << v1.capacity() << endl; //输出:2 cout << v1.size() << endl; //输出:2 v1.push_back(3); cout << v1.capacity() << endl; //输出:3 cout << v1.size() << endl; //输出:3 v1.push_back(4); cout << v1.capacity() << endl; //输出:4 cout << v1.size() << endl; //输出:4 v1.push_back(5); cout << v1.capacity() << endl; //输出:6 cout << v1.size() << endl; //输出:5}
从VS2015中就可以看出进行push_back操作时,与SGI STL中的扩容实现机制不一样;但是并不影响使用,在我们进行操作时,内部实现会自动帮我们检查空间是否需要增容。
例二(resize的用法):
void Test1(){ vector<int> v1;//定义一个数据类型为int的vector v1.push_back(2); cout << v1.size()<<endl; // 1 cout << v1.capacity()<<endl; // 1 v1.resize(5, 100); cout << v1.size() << endl; // 5 cout << v1.capacity() << endl; // 5 v1.resize(10); cout << v1.size() << endl; // 10 cout << v1.capacity() << endl; // 10 for (int i = 0; i < v1.size(); i++) { cout << v1[i] << " "; // 2 100 100 100 100 0 0 0 0 0 } cout << endl; v1.resize(4); cout << v1.size() << endl; // 4 cout << v1.capacity() << endl; // 10 for (int i = 0; i < v1.size(); i++) { cout << v1[i] << " "; //2 100 100 100 }}
小结:resize的函数原型:void resize (size_type n, value_type val = value_type());最主要的功能就是开空间并初始化。①如果只给n,没有给要初始化的值,就会对应开n个元素的大小,使得size == capcacity == n,并默认初始化为该类型的默认构造函数;②给n,给初始化的值,就会将新开辟的内容都初始化为给定的值;还有第二种功能是:如果n小于此时vector.capacity(),将vector的size更改为给定的n,多余的元素将被释放掉。
例三(reserve的用法):
void Test1(){ vector<int> v1;//定义一个数据类型为int的vector v1.resize(5); v1.reserve(10); for (int i = 0; i < v1.size(); i++) { cout << v1[i] << " "; // 0 0 0 0 0 } cout << endl; cout << v1.capacity() << endl; // 10 cout << v1.size() << endl; // 5 v1.reserve(2); for (int i = 0; i < v1.size(); i++) { cout << v1[i] << " "; } cout << endl; cout << v1.capacity() << endl; cout << v1.size() << endl; //由于n小于之前的capcacity,不进行任何操作}
小结:函数原型为:void reserve (size_type n); 功能:对capacity进行修改。如果n大于当前的vector的容量,则该函数会导致容器重新分配其存储空间,使其容量增加到n(或更大)。在所有其他情况下,函数调用并不会导致重新分配,而vector容量也不会受到影响。
例三(Iterator的用法):
void Test1(){ vector<int> v1;//定义一个数据类型为int的vector v1.resize(5,10); for (vector<int>::iterator it = v1.begin(); it != v1.end(); it++) { cout << *it << " "; }}
迭代器是一种模式,它可以使得对于序列类型的数据结构的遍历行为与被遍历的对象分离,即我们无需关心该序列的底层结构是什么样子的。只要拿到这个对象,使用迭代器就可以遍历这个对象的内部。至于关于vector内部迭代器使用的函数前面有表可以参考。更详细的就参考http://www.cplusplus.com/reference/vector/
下面是自己简单实现的vector:
template <class T>class Vector{public: typedef T* Iterator; typedef const T* ConstIterator; Vector() :_start(NULL) ,_finish(NULL) ,_EndOfStorage(NULL) {} size_t Size() { return _finish - _start; } size_t Capacity() { return _EndOfStorage - _start; } //T* _finish Iterator End() { return _finish; } Iterator Begin() { return _start; } void PushBack(const T& x) { Iterator end = End(); //T* end = (T*) _finish; Insert(end, x); } void Insert(Iterator& pos, const T& x) { size_t n = pos - _start; if (_finish == _EndOfStorage) { size_t len = Size() == 0 ? 3 : 2 * Capacity(); Expand(len); } pos = _start + n; for(Iterator end = End(); end != pos; --end) { *(end) = *(end-1); } *pos = x; ++_finish; } //多余的默认补充T(),否则为VAL void Resize(const size_t n,const T& val = T()) { //1 2 3 4 5 size=5 resize = 5 if (n < Size()) { _finish = _start + n; } else { Expand(n); size_t len = n - Size(); for (size_t i = 0; i < len; i++) { PushBack(val); } } } void Reverse(const size_t n) { Expand(n); } T& operator[](size_t pos) { assert(pos < Size()); return _start[pos]; } const T& operator[](size_t pos)const { assert(pos < Size()); return _start[pos]; } void Expand(size_t n) { const size_t size = Size(); const size_t capacity = Capacity(); if (n > capacity) { //开辟n空间,拷贝内容 T* tmp = new T[n]; for (size_t i = 0; i < size; i++) { tmp[i] = _start[i]; } delete[] _start; _start = tmp; _finish = _start + size; _EndOfStorage = _start + n; } } void PopBack() { assert(Size() > 0); Iterator end = End(); Erase(end); } void Erase(Iterator& pos) { assert(pos != NULL); for (Iterator end = pos; end < End(); end++) { _start[end-_start] = _start[(end + 1)-_start]; } --_finish; } size_t MaxSize() { return (0xffffffff / sizeof(T)); } void Print() { for (size_t i = 0; i < Size(); i++) { cout << _start[i] << " "; } cout << endl; }protected: Iterator _start; //head Iterator _finish; //size Iterator _EndOfStorage; //capacity};
阅读全文
0 0
- STL_Vector
- STL_vector
- STL_Vector
- STL_vector
- STL_vector<>
- STL_Vector
- STL_vector
- STL_vector 简析
- stl_vector.h
- STL_vector使用
- C++ STL_vector
- STL_vector常见用法举例
- stl_vector去重方法
- STL_vector的常用函数
- 《STL源码剖析》-- stl_vector.h
- 《STL源码剖析》-- stl_vector.h
- 《STL源码剖析》-- stl_vector.h
- STL_vector 顺序表操作1
- java 使用jedis操作redis
- CS231n----assignment1 -notes for KNN
- 自调用匿名函数
- 一些java小案例
- ORA-12514: TNS: 监听程序当前无法识别连接描述符中请求的服务
- STL_Vector
- WebStorm 11注册
- 第一篇
- JavaScript最佳新手入门系列之(ajax)
- 随笔(1)STM32F4——音频播放器
- 自定义可点击和滑动的按钮
- JAVA知识点梳理第二部分——接口、内部类、异常等等
- hdu1533(最小费用最大流spfa模板)
- jmu-ds-单链表的基本运算