数据结构之vector&list
来源:互联网 发布:爱知流量计 手机 编辑:程序博客网 时间:2024/06/06 01:08
一. vector & list的使用和区别
STL(标准模板库)是一个C++的软件库,也是C++标准程序库的一部分。vector和list相当于容器,这些容器应该都是STL里面的一个类。而vector封装数组,list封装链表。
vector
如代码:
#include<vector>
vector<int>a(10);//类型为int,数量为10
a[1] = { 1 };//第二个元素赋值为1
cout << a[1] << endl;//输出第二个元素
vector<int>::iterator pr = a.begin(); //迭代器指向第一个元素
pr++;
cout << *pr << endl;
//输出该元素的值
cout << a.size()
<< endl; //数组元素数量
a.front(); //数组第一个元素的引用
a.back(); //数组最后一个元素的引用
vector 类是以容器(Container) 模式为基准设计的,也就是说,基本上它有 begin(),end(),size(),max_size(),empty() 以及 swap() 这几个方法。
· 访问元素的方法
· vec[i] - 访问索引值为 i 的元素引用。 (索引值从零起算,故第一个元素是vec[0]。)
· vec.at(i) - 访问索引值为 i 的元素的引用,以 at() 访问会做数组边界检查,如果访问越界将会抛出一个例外,这是与operator[]的唯一差异。
· vec.front() - 回传 vector 第一个元素的引用。
· vec.back() - 回传 vector 最尾元素的引用。
· 新增或移除元素的方法
· vec.push_back() - 新增元素至 vector 的尾端,必要时会进行内存配置。
· vec.pop_back() - 删除 vector 最尾端的元素。
· vec.insert() - 插入一个或多个元素至 vector 内的任意位置。
· vec.erase() - 删除 vector 中一个或多个元素。
· vec.clear() - 清空所有元素。
· 获取长度/容量
· vec.size() - 获取 vector 目前持有的元素个数。
· vec.empty() - 如果 vector 内部为空,则传回 true 值。
· vec.capacity() - 获取 vector 目前可容纳的最大元素个数。这个方法与内存的配置有关,它通常只会增加,不会因为元素被删减而随之减少。
· 重新配置/重置长度
· vec.reserve() - 如有必要,可改变 vector 的容量大小(配置更多的内存)。在众多的 STL 实做,容量只能增加,不可以减少。
· vec.resize() - 改变 vector 目前持有的元素个数。
· 迭代 (Iterator)
· vec.begin() - 回传一个Iterator,它指向 vector 第一个元素。
· vec.end() - 回传一个Iterator,它指向 vector 最尾端元素的下一个位置(请注意:它不是最末元素)。
· vec.rbegin() - 回传一个反向Iterator,它指向 vector 最尾端元素的。
· vec.rend() - 回传一个Iterator,它指向 vector 的第一个元素。
list
一、list
在不懂的时候,list可以理解为双向链表(很像,但事实上不是)。
(1)声明一个list对象:
①包含头文件list:#include<list>
②声明他:std::list<int> one; //声明一个list对象
③需要注意,list位于std名称空间之中,因此如果使用using namespace std,可以省略std::
(2)使用 迭代器:
①迭代器,在不懂的时候,可以理解为指针,指向对象。但事实上,迭代器不是指针(例如,指针可以加一个int值,但迭代器是不可以的)。
②声明一个list类迭代器:std::list<int>::iterator pr = one.begin(); //一个迭代器,用于指向one的第一个对象
③迭代器可以使用++和--这样的形式;
pr++;
pr--;
++pr;
--pr;
效果是:++(指向list对象内的下一项),--(指向上一个项);
Note:假如当前迭代器已经指向最后或最初,则不能超出界限,否则会出错(例如最后时不能+,第一个时不能-)
④利用迭代器插入一个成员(有疑问)。
int a = 1;
one.insert(pr, a);
//注意,根据观察,每添加一个对象,迭代器便会自动指向下一个位置。
⑤查询当前容器里有多少个项目:
cout << one.size();
⑥删除一个成员
更多的使用,参考链接:
http://www.cppblog.com/Lee7/archive/2008/04/14/47036.html
成员函数概观[编辑]
· 迭代(Iterator)
· list.begin() 回传指向第一个元素的Iterator。
· list.end() 回传指向最末元素的下一个位置的Iterator。
· list.rbegin() 回传指向最末个元素的反向Iterator。
· list.rend() 回传指向第一个元素的前一个位置的反向Iterator。
· Capacity/Size:
· list.empty() 若list内部为空,则回传true值。
· list.size() 回传list内实际的元素个数。
· list.resize() 重新分派list的长度。
· 存取元素的方法
· list.front() 存取第一个元素。
· list.back() 存取最末个元素。
· Modify methods
· list.push_front() 增加一个新的元素在list的前端。
· list.pop_front() 删除list的第一个元素。
· list.push_back() 增加一个新的元素在list的尾端。
· list.pop_back() 删除list的最末个元素。
· list.insert() -插入一个或多个元素至list内的任意位置。
· list.erase() -删除list中一个或多个元素。
· list.clear() -清空所有元素。
· 重新配置/重设长度
· list.reserve() -如有必要,可改变list的容量大小(配置更多的内存)。
· list.resize() -改变list目前持有的元素个数。
二. 模拟实现MyVectorvector可以把它理解成一个顺序表或者数组。只是STL里的vector是由三个迭代器来维护的:_start(数据存放开始的位置),_finish(数据存放结束位置的下一个),_endofstorage(容量的最后一个位置)。vector里的迭代器其实就是个指针。
#include<iostream> #include<vector> using namespace std; template<class T> class MyVector { public: typedef T* Iterator; typedef const T* ConstIterator; MyVector(size_t n=3) //构造函数,初始化给3个T类型容量 :_start(new T[n]), _finish(_start), _end_of_storage(_start+n) { } MyVector(const MyVector<T>& v) //拷贝构造 { if (v._finish - v._start > _finish - _start) { delete[] _start; _start = new T[v._finish - v._start]; _finish = _start; } for (Iterator tmp = v._start; tmp != v._finish; tmp++) { *(_finish) = *tmp; _finish++; } _end_of_storage = _finish; } void PushBack(const T& x) //尾插,这里注意,即使调用的insert里检查了容量,尾插函数仍需检测 { CheckCapacity(); Insert(End(), x); } void PopBack() { Iterator pos = End(); //前置的--因为返回的是临时变量的值,所以不能直接对End()函数进行-- Erase(--pos); } void Insert(Iterator pos, const T& x) { CheckCapacity(); for (Iterator tmp = End(); tmp != pos;tmp--) { *tmp = *(tmp - 1); } *pos = x; _finish++; } void Erase(Iterator pos) { Iterator end = End(); for (Iterator tmp = pos; tmp != (--end); tmp++) { *tmp = *(tmp + 1); } _finish--; } size_t Size() { return _finish - _start; } /************迭代器部分***********/ Iterator Begin() { return _start; } Iterator End() { return _finish; } /*Iterator operator++(int) { Iterator tmp = *this; tmp++; return tmp; } Iterator& operator++() { Iterator tmp = *this; tmp++; return *this; } Iterator operator--(int) { Iterator tmp = *this; tmp--; return tmp; } Iterator& operator--() { Iterator tmp = *this; tmp--; return *this; } */ private: void CheckCapacity() { if (_finish == _end_of_storage) { Iterator new_start = new T[2 * Size()]; //一次扩容原来的两倍 Iterator new_finish = new_start; for (Iterator i = Begin(); i != End(); i++,new_finish++) { *new_finish = *i; } delete[] _start; _start = new_start; _finish = new_finish; _end_of_storage = _start + 2 * Size(); } } private: Iterator _start; Iterator _finish; Iterator _end_of_storage; };三. 模拟实现MyList
#include<cstddef> #include<memory> //list的节点结构 template<typename T> struct list_node{ typedef list_node<T>* pointer; pointer prev; pointer next; T data; }; //list的iterator template<typename T> struct list_iterator{ //嵌套型别定义 typedef T value_type; typedef T* pointer; typedef const T* const_pointer; typedef T& reference; typedef const T& const_reference; typedef size_t size_type; typedef ptrdiff_t difference_type; typedef list_iterator<T> iterator; typedef list_node<T>* link_type; link_type node; //指向list的节点 list_iterator(link_type p = nullptr) :node(p){}//构造函数 reference operator*() const { return node->data; } //重载运算符* pointer operator->() const { return &(operator*()); }//重载运算符-> iterator operator++(){ //前++ node = node->next; return *this; } iterator operator++(int){//后++ iterator temp = *this; ++*this; return temp; } iterator operator--(){//前-- node = node->prev; return *this; } iterator operator--(int){//后-- iterator temp = *this; --*this; return temp; } bool operator==(const iterator& it){ return node == it.node; }//重载运算符== bool operator!=(const iterator& it){ return node != it.node; }//重载运算符!= }; //list template<typename T> class MyList{ public: //嵌套型别定义 typedef T value_type; typedef T* pointer; typedef const T* const_pointer; typedef T& reference; typedef const T& const_reference; typedef size_t size_type; typedef ptrdiff_t difference_type; typedef list_iterator<T> iterator; typedef const list_iterator<T> const_iterator; typedef list_node<T>* link_type; protected: link_type node; //一个指针可以表示整个环状双向链表 std::allocator<list_node<T>> alloc;//空间分配器 public: MyList();//默认构造函数 MyList(size_type n, const T& value);//构造函数 template<typename InputIterator> MyList(InputIterator first, InputIterator last);//构造函数 ~MyList();//析构函数 MyList(MyList& lst);//拷贝构造函数 MyList& operator=(MyList& lst);//拷贝赋值运算符 protected: void empty_initialize(){ node = get_node(); node->prev = node; node->next = node; } link_type get_node(){ return alloc.allocate(1); }//配置一个节点 void put_node(link_type p){ alloc.deallocate(p, 1); }//释放一个节点 link_type create_node(const T& value){//产生一个节点 link_type temp = get_node(); new (&temp->data) T(value); //定位new,在指定地址处构造对象 return temp; } void destroy_node(link_type p){ //销毁一个节点 (&p->data)->~T(); put_node(p); } public: iterator begin(){ return node->next; } const_iterator begin() const { return node->next; } iterator end(){ return node; } const_iterator end() const { return node; } size_type size() const { size_type count = 0; link_type p = node->next; while (p != node){ ++count; p = p->next; } return count; } bool empty() const { return node->next == node; } reference front(){ return *begin(); } const_reference front() const { return *begin(); } reference back(){ return *(--end()); } const_reference back() const { return *(--end()); } void push_back(const T& value); void pop_back(); void push_front(const T& value); void pop_front(); iterator insert(iterator position,const T& value); void insert(iterator position, size_type n, const T& value); iterator erase(iterator position); iterator erase(iterator first, iterator last); void remove(const T& value); void clear(); void splice(iterator position, MyList& lst); void splice(iterator position, MyList& lst, iterator it); void splice(iterator position, MyList& lst, iterator first, iterator last); void merge(MyList& lst); void reverse(); void swap(MyList& lst); void sort(); void unique(); protected: void transfer(iterator position, iterator first, iterator last); }; //默认构造函数 template<typename T> MyList<T>::MyList(){ empty_initialize(); } //构造函数 template<typename T> MyList<T>::MyList(size_type n, const T& value){ empty_initialize(); for (; n > 0; --n) insert(end(), value); } ////构造函数 template<typename T> template<typename InputIterator> MyList<T>::MyList(InputIterator first, InputIterator last){ empty_initialize(); for (InputIterator it = first; it != last; ++it) insert(end(), *it); } //析构函数 template<typename T> MyList<T>::~MyList(){ clear(); destroy_node(node); node = nullptr; } //拷贝构造函数 template<typename T> MyList<T>::MyList(MyList& lst){ empty_initialize(); for (iterator it = lst.begin(); it != lst.end(); ++it) insert(end(), *it); } //拷贝赋值运算符 template<typename T> MyList<T>& MyList<T>::operator=(MyList& lst){ if (lst != *this){ clear(); for (iterator it = lst.begin(); it != lst.end(); ++it) insert(end(), *it); return *this; } } //push_back(const T& value) template<typename T> void MyList<T>::push_back(const T& value){ insert(end(), value); } //pop_back() template<typename T> void MyList<T>::pop_back(){ iterator temp = end(); erase(--temp); } //push_front(const T& value) template<typename T> void MyList<T>::push_front(const T& value){ insert(begin(), value); } //pop_front() template<typename T> void MyList<T>::pop_front(){ erase(begin()); } //insert(iterator position, const T& value) template<typename T> typename MyList<T>::iterator MyList<T>::insert(iterator position, const T& value){ link_type p = create_node(value); position.node->prev->next = p; p->prev = position.node->prev; position.node->prev = p; p->next = position.node; return p; } //insert(iterator position, size_type n, const T& value) template<typename T> void MyList<T>::insert(iterator position, size_type n, const T& value){ while (n > 0){ insert(position, value); --n; } } //erase(iterator position) template<typename T> typename MyList<T>::iterator MyList<T>::erase(iterator position){ link_type prev_node = position.node->prev; link_type next_node = position.node->next; prev_node->next = next_node; next_node->prev = prev_node; destroy_node(position.node); return iterator(next_node); } //erase(iterator first, iterator last) template<typename T> typename MyList<T>::iterator MyList<T>::erase(iterator first, iterator last){ for (iterator it = first; it != last; ++it) erase(it); return last; } //remove(const T& value) template<typename T> void MyList<T>::remove(const T& value){ iterator first = begin(); iterator last = end(); while(first!=last){ iterator next = first; ++next; if (*first == value) erase(first); first = next; } } //clear() template<typename T> void MyList<T>::clear(){ for (iterator it = begin(); it != end(); ++it){ iterator next = it; ++next; erase(it); it = next; } node->prev = node; node->next = node; } //transfer(iterator position, iterator first, iterator last) template<typename T> void MyList<T>::transfer(iterator position, iterator first, iterator last){ link_type first_node = first.node; link_type befor_last_node = last.node->prev; first_node->prev->next = befor_last_node->next; befor_last_node->next->prev = first_node->prev; position.node->prev->next = first_node; first_node->prev = position.node->prev; befor_last_node->next = position.node; position.node->prev = befor_last_node; } //splice(iterator position, MyList& lst) template<typename T> void MyList<T>::splice(iterator position, MyList& lst){ if (!lst.empty()) transfer(position, lst.begin(), lst.end()); } //splice(iterator position, MyList& lst, iterator it) template<typename T> void MyList<T>::splice(iterator position, MyList& lst, iterator it){ iterator it2 = it; ++it2; if (position == it || position == it2) return; transfer(position, it, it2); } //splice(iterator position, MyList& lst, iterator first, iterator last) template<typename T> void MyList<T>::splice(iterator position, MyList& lst, iterator first, iterator last){ if (first != last) transfer(position, first, last); } //merge(MyList& lst) template<typename T> void MyList<T>::merge(MyList& lst){ iterator begin1 = begin(); iterator end1 = end(); iterator begin2 = lst.begin(); iterator end2 = lst.end(); while (begin1 != end1&&begin2 != end2){ if (*begin2 < *begin1){ iterator next = begin2; ++next; transfer(begin1, begin2, next); begin2 = next; }else ++begin1; } if (begin2 != end2) transfer(end1, begin2, end2); } //reverse() template<typename T> void MyList<T>::reverse(){ if (node->next == node || node->next->next == node) return; iterator first = begin(); ++first; while (first != end()){ iterator old = first; ++first; transfer(begin(), old, first); } } //swap(MyList& lst) template<typename T> void MyList<T>::swap(MyList& lst){ if (node != lst.node){ link_type temp = lst.node; lst.node = node; node = temp; } } //sort() template<typename T> void MyList<T>::sort(){ if (node->next == node || node->next->next == node) return; MyList<T> carry; MyList<T> counter[64]; int fill = 0; while (!empty()){ carry.splice(carry.begin(), *this, begin()); int i = 0; while (i < fill&&!counter[i].empty()){ counter[i].merge(carry); carry.swap(counter[i++]); } carry.swap(counter[i]); if (i == fill) ++fill; } for (int i = 1; i < fill; ++i) counter[i].merge(counter[i - 1]); swap(counter[fill - 1]); } template<typename T> void MyList<T>::unique(){ iterator first = begin(); iterator last = end(); if (first == last) return; iterator next = first; while (++next != last){ if (*first == *next) erase(next); else first = next; next = first; } }
- 数据结构List之Vector
- 数据结构之vector&list
- 数据结构之Vector
- 数据结构之vector
- 【一】 数据结构之Vector
- 【数据结构】STL中的vector和list
- vector 与list 之erase
- STL之list/vector/deque
- java数据结构之向量Vector
- java数据结构之List
- 数据结构List之ArrayList
- 数据结构List之LinkedList
- 【二】数据结构之List
- 数据结构之List
- Java 常用数据结构深入分析(Vector、ArrayList、List、Map)
- Java 常用数据结构深入分析(Vector、ArrayList、List、Map)
- C++存储数据结构List、CArray、Vector和Map使用分析
- Java 常用数据结构深入分析(Vector、ArrayList、List、Map)
- css实现背景透明文字不透明
- redise数据结构之之字符串和链表
- UnityShader初级篇——实现逐像素漫反射光照模型
- 【转】gcc for Windows 开发环境介绍
- (四)ElasticSearch索引创建
- 数据结构之vector&list
- iOS UI事件传递与响应者链
- ROS--urdf在rviz之中的显示(补充)
- built-in function 错误的解决
- 初学python遇到的问题大全
- MacOS连接树莓派3(Raspberry Pi 3)
- Codeforces Gym-101116-F (Flight Plan)
- Android Studio Warning警告系列
- test