Vector_list的使用和模拟
来源:互联网 发布:电脑优化软件知乎 编辑:程序博客网 时间:2024/06/08 07:35
1.初步了解和使用vector list
·vector实质是一个动态增长数组,list是一个链表,他们都是STL的一种容器。
①使用vector
#vector使用样例代码:
#pragma once#include<iostream>using namespace std;#include<vector>void test_vector(){ vector<int> v; v.push_back(1); v.push_back(2);//尾插 v.push_back(3); v.push_back(4); v.push_back(5); vector<int>::iterator it = v.begin();//迭代器 while (it != v.end()) { cout << *it << " "; ++it; } it--; v.insert(it, 0);//在目标位之前插入 cout << endl; it = v.begin(); while (it != v.end()) { cout << *it << " "; it++; } cout << endl; --it; v.erase(it);//对目标位置进行删除 it = v.begin(); while (it != v.end()) { cout << *it << " "; it++; } cout << endl; v.resize(10,5);//改变vector size大小,并对新添加的空间初始化; it = v.begin(); while (it != v.end()) { cout << *it << " "; it++; } cout << endl; v.reserve(100);//改变数组容量,不进行初始化 it = v.begin(); while (it != v.end()) { cout << *it << " "; it++; } cout << endl; cout << v.size() << endl;//size()返回数组当前所用的数据个数 cout << v.capacity() << endl;//capacity()返回数组的容量}
·通过上面的使用我们了解vector各个接口的功能,对于插入我只是用了push_back、insert接口,头插和尾插是一样的效果;还有迭代器我只是用了iterator,其实他还有consr_iterator、reverse_iterator其实用法都是一样的;接下来我们再来了解一下list的用法和接口功能;
在这里我得讲清楚一个问题迭代器失效,首先它的场景是这样的:
while (it != v.end()) { if (*it % 2 == 0) { v.erase(it); } it++; }
·分析当这句代码执行第一次循环是会挂掉,原因是这样的:第一次执行他的时候,v.erase(it)删掉了这个位置,而it在vector下的实际情况是一个指针,所以当删掉它的时候就会出现像野指针这样的问题,再对他进行加加操作时就再找不到它的位置了;
·关于vector迭代器失效问题有以下接解决方案:
while (it != v.end()) { if (*it % 2 == 0) { it=v.erase(it);//erase返回it得下一个位置(迭代器类型) } else { it++; } }
·erase删除的时候会返回的他的下一个位置的迭代器
②list的使用代码:
#include<iostream>#include<list>#include<vector>using namespace std;void testlist(){ list<int> l; l.push_back(5); l.push_back(4); l.push_back(3); l.push_back(2); l.push_back(1);//尾插 list<int>::iterator it = l.begin(); while (it != l.end())//顺序打印 { cout << *it << " "; it++; } cout << endl; l.push_front(0);//头插 list<int>::reverse_iterator it1 = l.rbegin();//反向迭代器 while (it1 != l.rend())//逆序打印 { cout << *it1 << " "; it1++; } cout << endl; l.resize(5); l.resize(8,100); l.resize(12);//resize改变链表的size大小并对其进行初始化,默认初始化为零 list<int>::iterator it2 = l.begin();//迭代器 while (it2 != l.end())//顺序打印 { cout << *it2 << " "; it2++; } cout << endl;}void test_vector(){ vector<int> v; v.push_back(1); v.push_back(2); v.push_back(3); v.push_back(4); v.push_back(5); v.push_back(6); vector<int>::iterator it = v.begin(); while (it != v.end()) { cout << *it << " "; it++; } it--; while (it != v.end()) { cout << *it << " "; it++; }}
·其实不难发现list 和 vector的接口有一些共同点,他们都有自己的迭代器(const_iterator、iterator、reverse_iterator);还有一些关于插入删除的接口入(push_back、push_front、insert)、(pop_back、pop_front、erase);还有改变size大小的接口;
·最最重要是:list同样有迭代器失效问题;
2.模拟实现vector_list
·模拟实现vector
template<class T>class Vector{public: typedef T* Iterator;//普通迭代器 typedef const T* C_Iterator;//const 迭代器 typedef T* R_Iterator; Vector() :_start(NULL) , _finish(NULL) , _endOfStorage(NULL) { } Iterator End() { return _finish; } Iterator Begin() { return _start; } C_Iterator CBegin() { return _start; } C_Iterator CEnd() { return _finish; } R_Iterator RBegin() { if (_finish>=_start) return (_finish - 1); } R_Iterator REnd() { return (_start - 1); } void PushBack(const T& data)//尾插 { if (_finish == _endOfStorage)//判断是否需要增容 { size_t len = Capacity() == 0 ? 3 : 2 * Capacity(); Expend(len); } size_t size = Size(); _start[size] = data; _finish++; } void PopBack() { if (_finish!=_start) _finish--; } void PushFront(const T& data)//前插 { if (_finish == _endOfStorage)//判断是否需要增容 { size_t len = Capacity() == 0 ? 3 : 2 * Capacity(); Expend(len); } for (Iterator i = End(); i >= _start; i--)//挪动数据 { *i = *(i-1); } _start[0] = data; _finish++; } void PopFront()//头删 { for (Iterator i = Begin(); i < End()-1; i++) { *i = *(i + 1); } _finish--; } void Insert(Iterator& pos, const T& data)//在pos的前一个位置插入 { size_t n = pos - _start; if (_finish == _endOfStorage) { size_t len = Capacity() == 0 ? 3 : 2 * Capacity(); Expend(len); } for (Iterator end = End(); end >= pos; --end) { *end = *(end - 1); } *(_start + n) = data; _finish++; } Iterator Erase(Iterator pos)//删除任意位置,删除后返回跌代器类型,返回下一位置 { assert(pos<_finish); Iterator tmp = pos+1; for (Iterator i = pos; i < End() - 1; i++) { *i = *(i + 1); } _finish--; return tmp; } void Expend(size_t n)//扩容 { size_t size = Size(); size_t capacity = Capacity(); if (n > capacity) { 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; } } size_t Capacity()//返回容量大小 { return _endOfStorage - _start; } size_t Size()//返回当前拥有元素个数 { return _finish - _start; }protected: Iterator _start; Iterator _finish; Iterator _endOfStorage;};
·注意在实现Erase时返回的下一位置迭代器;
·实现list
#include<iostream>#include<assert.h>using namespace std;template <class T>struct ListNode{public: ListNode(T data = T()) :_next(NULL) , _prev(NULL) , _data(data) { } ListNode* _next; ListNode* _prev; T _data;};template<class T, class Ptr, class Ref>class Iterator{ typedef ListNode<T> Node; typedef Iterator<T,Ptr,Ref> self;public: Iterator(Node* node) :node(node) { } Ref operator*() { return node->_data; } Ptr operator->() { return &(node->_data); } self operator ++()//前置加加 { node = node->_next; return self(node); } self operator --()//前置减减 { node = node->prev; return self(node); } self operator ++(int)//后置加加 { Node* tmp = node; node = node->_next; return self(tmp); } self operator --(int)//后置减减 { Node* tmp = node; node = node->prev; return self(tmp); } bool operator != (Iterator& I) { return node != I.node; } bool operator == (Iterator& I) { return node == I.node; }public: Node* node;};template<class T>class Reverse_Iterator{ typedef ListNode<T> Node; typedef Reverse_Iterator<T> self; public: Reverse_Iterator(Node* node) :node(node) { } T& operator *() { return node->_data; } T* operator->() { return &(node->_data); } self operator ++()//前置加加 { node = node->_prev; return self(node); } self operator --()//前置减减 { node = node->_next; return self(node); } self operator ++(int)//后置加加 { Node* tmp = node; node = node->_prev; return self(tmp); } self operator --(int)//后置减减 { Node* tmp = node; node = node->_next; return self(tmp); } bool operator != (Reverse_Iterator& I) { return node != I.node; } bool operator == (Reverse_Iterator& I) { return node == I.node; } public: Node* node;};template <class T>class List{public: typedef ListNode<T> Node; typedef Iterator<T,T*,T&> iterator; typedef Reverse_Iterator<T> reverse_iterator; typedef Iterator<T,const T*,const T&> c_iterator;public: List() :_head(new Node) { _head->_next = _head; _head->_prev = _head; } reverse_iterator rBegin() { return reverse_iterator(_head->_prev); } reverse_iterator rEnd() { return reverse_iterator(_head); } iterator Begin() { return iterator(_head->_next); } iterator End() { return iterator(_head); } c_iterator cBegin() const { return c_iterator(_head->_next); } c_iterator cEnd() const { return c_iterator(_head); } void PushBack(const T& data) { Node* tail = _head->_prev; Node* tmp = new Node(data); tail->_next = tmp; tmp->_prev = tail; tmp->_next = _head; _head->_prev = tmp; } void PopBack() { if (_head->_prev != _head)//判断是否只有一个节点 { Node* tail = _head->_prev; Node* newtail = tail->_prev; _head->_prev = newtail; newtail->_next = _head; delete tail; } } void PushFront(const T& data) { Node* next = _head->_next; Node* tmp = new Node(data); _head->_next = tmp; tmp->_next = next; tmp->_prev = _head; next->_prev = tmp; } void PopFront() { //1.判断有没有节点 if (_head->_next != _head) { Node* tmp = _head->_next; Node* newnext = tmp->_next; _head->_next = newnext; newnext->_prev = _head; delete tmp; } } void Insert(iterator& pos, const T& data) { Node* prev = pos.node->_prev; Node* tmp = new Node(data); prev->_next = tmp; tmp->_prev = prev; tmp->_next = pos.node; pos.node->_prev = tmp; } iterator Erase(iterator& pos) { //删除pos得找到它的前一个和后一个 assert(pos.node != _head); Node* prev = pos.node->_prev; Node* next = pos.node->_next; prev->_next = next; next->_prev = prev; delete pos.node; return iterator(next); }protected: Node* _head;};template<class T>void rprint( List<T>& l){ List<int>::reverse_iterator it = l.rBegin(); while (it != l.rEnd()) { cout << *it << " "; it++; } cout << endl;}template<class T>void print(List<T>& l){ List<int>::iterator it = l.Begin(); while (it != l.End()) { cout << *it << " "; it++; } cout << endl;}
阅读全文
0 0
- Vector_list的使用和模拟
- 栈的使用和模拟
- makefile的使用和模拟实现进度条
- SearchView的简单使用和模拟搜索
- 模拟填ip时的功能和onkeyup的使用
- 使用java简单模拟ping和telnet的实现
- 使用java简单模拟ping和telnet的实现
- 使用java简单模拟ping和telnet的实现
- 使用java简单模拟ping和telnet的实现
- 使用java简单模拟ping和telnet的实现
- 使用java简单模拟ping和telnet的实现
- python 网络报文模拟和端口扫描库 scapy的使用
- java的URL类使用和模拟POST请求服务器
- 使用R的金融统计:收益、随机行走和模拟
- 使用JAVA注解和反射模拟spring的IOC
- Android 按键模拟输入事件和Monitor工具的使用
- fiddler抓包软件模拟GET和POST的使用
- STL库中的vector的使用和模拟实现
- list多条目加载
- 缓存淘汰算法--LRU算法
- 微信小程序拼团功能之表结构
- Learning Spatiotemporal Features with 3D Convolutional Networks译
- 在eclipse中给jar包导入javadoc文件
- Vector_list的使用和模拟
- HDU 5655 CA Loves Stick
- Invocation of init method failed; nested exception is org.activiti.engine.ActivitiException: couldn'
- 学习笔记 div span 垂直居中 + 水平居中
- 【UE4-节点】 美术学习笔记和经验_liuk718
- 自定义异常--继承RuntimeException
- MVP架构分包+OkHttp网络请求数据并展示到xrecyclerview上
- Web Server配置介绍
- 多线程和异步的区别