数据结构之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目前持有的元素个数。

二. 模拟实现MyVector

vector可以把它理解成一个顺序表或者数组。只是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;      }  } 



 


原创粉丝点击