(第二步) STL: stl_list容器的实现

stl_list容器

工具:visual studio 2019

STL标准模板库中实现的是双向环形链表,这里就实现了普通双向链表

在stl_list.impl.h部分做了详细的注释

实现功能

基本功能实现:
list.back()         返回最后一个元素 
list.begin()         返回指向第一个元素的迭代器 
list.clear()         删除所有元素 
list.empty()         如果list是空的则返回true 
list.end()             返回末尾的迭代器 
list.erase()         删除一个元素 
list.front()         返回第一个元素 
list.insert()         插入一个元素到list中
list.pop_back()     删除最后一个元素 
list.pop_front()     删除第一个元素 
list.push_back()     在list的末尾添加一个元素 
list.push_front()     在list的头部添加一个元素
list.resize()         改变list的大小
list.size()         返回list中的元素个数
list.swap()         交换两个list 

丰富功能函数的实现:
list.splice()         直接合并两个list 
list.merge()         默认按小到大,合并两个list 
list.rbegin()         返回指向第一个元素的逆向迭代器 
list.rend()         指向list末尾的逆向迭代器
list.remove()         从list删除元素 
list.remove_if()    按指定条件删除元素 
list.unique()         删除list中重复的元素
list.reverse()         把list的元素倒转 
list.sort()         给list排序 

stl_list.h

 #ifndef _LIST_H_
 #define _LIST_H_
 ​
 #include "../Includes/Allocator.h"
 #include "../Includes/Iterator.h"
 #include "../Includes/ReverseIterator.h"
 #include "../Includes/UninitializedFunctions.h"
 #include "../Includes/Utility.h"
 ​
 #include <type_traits>
 ​
 namespace mySTL {
     template<class T>
     class list;
     namespace detail {
         // 设置链表的每个节点
         template<class T>
         struct node {
             T data;
             node* prev;
             node* next;
 ​
             node(const T& d, node* p, node* n) :
                 data(d), prev(p), next(n){}
 ​
             // 节点相等的情况
             bool operator ==(const node& n) {
                 return data == n.data && prev == n.prev && next == n.next;
             }
         };
 ​
         // 迭代器类型
         template<class T>
         struct listIterator :public iterator<bidirectional_iterator_tag, T> {
                 template<class T>
                 friend class list;          //友元访问,互相为好基友,相互访问
             public:
                 typedef node<T>* nodePtr;
                 nodePtr p;
 ​
             public:
                 explicit listIterator(nodePtr ptr = nullptr):p(ptr){}
 ​
                 listIterator& operator++();                      //++i
                 listIterator operator++(int);                    //i++
                 listIterator& operator--();                     //
                 listIterator operator--(int);                    //
 ​
                 T& operator *() { return p->data; }
                 T* operator ->() { return &(operator*()); }
                 
 ​
                 // 友元函数必须类内定义、类外声明(不确定,但是类内声明实现不了int以外的类型)
                 template<class T>
                 friend bool operator==(const listIterator<T>& lhs, const listIterator<T>& rhs); 
 ​
                 template<class T>
                 friend bool operator!=(const listIterator<T>& lhs, const listIterator<T>& rhs);
 ​
             };
         }
 ​
     template<class T>
     class list {
         template<class T>
         friend struct listIterator;             //友元,互相为好基友
     private:
         typedef allocator<detail::node<T>>      nodeAllocator;
         typedef detail::node<T>*                nodePtr;
 ​
     public:
         typedef T                               value_type;
         typedef detail::listIterator<T>         iterator;
         typedef detail::listIterator<const T>   const_iterator;
         typedef reverse_iterator_t<iterator>    reverse_iterator;
         typedef T&                              reference;
         typedef size_t                          size_type;
     private:
         iterator head;
         iterator tail;
 ​
         nodePtr newNode(const T& val = T());
         void deleteNode(nodePtr p);
 ​
     public:
         // 构造和析构函数
         list();
         explicit list(size_type n, const value_type& val = value_type());
         template <class InputIterator>
         list(InputIterator first, InputIterator last);
         // 注意,这里使用的是浅拷贝
         list(const list& l);
         list& operator=(const list& l);
 ​
         ~list();
     
         // 查看元素
     public:
         bool empty()const { return head == tail; }
         size_type size()const;
         reference front() { return (head.p->data); }
         reference back() { return (tail.p->prev->data); }
 ​
         iterator begin() { return head; }
         iterator end() { return tail; }
 ​
         // 逆序迭代器,拓展功能
         reverse_iterator rbegin();
         reverse_iterator rend();
 ​
         // 元素操作的基本操作
     public:
         void push_front(const value_type& val);
         void pop_front();
         void push_back(const value_type& val);
         void pop_back();
 ​
         iterator insert(iterator position, const value_type& val);
         void insert(iterator position, size_type n, const value_type& val);
         template <class InputIterator>
         void insert(iterator position, InputIterator first, InputIterator last);
         iterator erase(iterator position);
         iterator erase(iterator first, iterator last);
         void clear(); ​        
         void swap(list& x);

         // 拓展丰富功能
         void splice(iterator position, list& x);        
         void splice(iterator position, list& x, iterator first, iterator last);
         void splice(iterator position, list& x, iterator i);
         void merge(list& x);
         template <class Compare>
         void merge(list& x, Compare comp);
 ​
         void remove(const value_type& val);
         template <class Predicate>
         void remove_if(Predicate pred);
         void unique();
         template <class BinaryPredicate>
         void unique(BinaryPredicate binary_pred);
         void sort();
         template <class Compare>
         void sort(Compare comp);
         void reverse();
 ​
         // 辅助函数
     private:
         void ctorAux(size_type n, const value_type& val, std::true_type);
         template <class InputIterator>
         void ctorAux(InputIterator first, InputIterator last, std::false_type);     
         void insert_aux(iterator position, size_type n, const T& val, std::true_type);
         template<class InputIterator>
         void insert_aux(iterator position, InputIterator first, InputIterator last, std::false_type);
 ​
     public:
         template<class T>
         friend void swap(list<T>& x, list<T>& y);
         template <class T>
         friend bool operator== (const list<T>& lhs, const list<T>& rhs);
         template <class T>
         friend bool operator!= (const list<T>& lhs, const list<T>& rhs);
     };
 }
 ​
 #include "../Detail/stl_list.impl.h"
 ​
 #endif

stl_list.impl.h

 #include "..\p2_STL_Source\stl_list.h"
 ​
 #ifndef _LIST_IMPL_H_
 #define _LIST_IMPL_H_
 ​
 namespace mySTL {
     namespace detail {
         // 实现重载++,--功能
         template<class T>
         inline listIterator<T>& listIterator<T>::operator++()
         {
             p = p->next;
             return *this;
         }
 ​
         template<class T>
         inline listIterator<T> listIterator<T>::operator++(int)
         {
             auto res = *this;
             p = p->next;
             return res;
         }
 ​
         template<class T>
         inline listIterator<T>& listIterator<T>::operator--()
         {
             p = p->prev;
             return *this;
         }
 ​
         template<class T>
         inline listIterator<T> listIterator<T>::operator--(int)
         {
             auto res = *this;
             p = p->prev;
             return res;
         }
 ​
         template<class T>
         bool operator ==(const listIterator<T>& lhs, const listIterator<T>& rhs) {
             return lhs.p == rhs.p;
         }
 ​
         template<class T>
         bool operator !=(const listIterator<T>& lhs, const listIterator<T>& rhs) {
             return !(lhs == rhs);
         }
 ​
     }
 ​
     // 构造、拷贝、析构函数
     // 新建节点
     template<class T>
     inline typename list<T>::nodePtr list<T>::newNode(const T& val)
     {
         // 申请空间
         nodePtr res = nodeAllocator::allocate();
         // 初始化节点
         nodeAllocator::construct(res, detail::node<T>(val, nullptr, nullptr));
 ​
         return res;
     }
 ​
     // 无参构造,新建一个节点,head == tail
     template<class T>
     list<T>::list()
     {
         head.p = newNode(); // 虚假节点dummy
         tail.p = head.p;
     }
 ​
 ​
     // 删除节点
     template<class T>
     inline void list<T>::deleteNode(nodePtr p)
     {
         p->prev = p->next = nullptr;
         nodeAllocator::destroy(p);      // 调用p的析构
         nodeAllocator::deallocate(p);   // free空间释放
     }
 ​
     // 析构
     template<class T>
     inline list<T>::~list()
     {
         while (head != tail)
         {
             auto temp = head++;
             nodeAllocator::destroy(temp.p);     // 调用p的析构
             nodeAllocator::deallocate(temp.p);  // free空间释放
         }
         nodeAllocator::destroy(tail.p);     // 调用p的析构
         nodeAllocator::deallocate(tail.p);  // free空间释放
     }
 ​
     /************************查看元素**************************/
 ​
     template<class T>
     typename list<T>::size_type list<T>::size()const
     {
         size_type len = 0;
         for (auto h = head; h != tail; ++h)
         {
             ++len;
         }
 ​
         return len;
     }
 ​
     /************************元素基本操作**************************/
     /****************实现push、pop、insert、erase、clear功能************************/
     template<class T>
     inline void list<T>::push_front(const value_type& val)
     {
         auto node = newNode(val);
         head.p->prev = node;
         node->next = head.p;
         head.p = node;
     }
 ​
     template<class T>
     void list<T>::pop_front() 
     {
         auto oldNode = head.p;
         head.p = oldNode->next;
         head.p->prev = nullptr;
         deleteNode(oldNode);
     }
 ​
     template<class T>
     inline void list<T>::push_back(const value_type& val)
     {
         auto node = newNode(val);
         tail.p->data = val;
         tail.p->next = node;
         node->prev = tail.p;
         tail.p = node;
     }
 ​
     template<class T>
     void list<T>::pop_back() 
     {
         auto oldNode = tail.p;
         tail.p = oldNode->prev;
         tail.p->next = nullptr;
         deleteNode(oldNode);
     }
 ​
     template<class T>
     inline typename list<T>::iterator list<T>::insert(iterator position, const value_type& val)
     {
         if (position == begin())
         {
             push_front(val);
             return begin();
         }
         else if (position == end())
         {
             push_back(val);
             auto ret = position;
             return ret;
         }
 ​
         auto node = newNode(val);
         auto prev = position.p->prev;
         node->next = position.p;        
         node->prev = prev;
         prev->next = node;
         position.p->prev = node;
 ​
         return iterator(node);
     }
 ​
     template<class T>
     inline typename list<T>::iterator list<T>::erase(iterator position)
     {
         if (position == head)
         {
             pop_front();
             return head;
         }
         else
         {
             auto prev = position.p->prev;
             prev->next = position.p->next;
             position.p->next->prev = prev;
             deleteNode(position.p);
             return iterator(prev->next);
         }
     }
 ​
     template<class T>
     inline typename list<T>::iterator list<T>::erase(iterator first, iterator last)
     {
         typename list<T>::iterator ret;
         while (first != last)
         {
             auto temp = first++;
             ret = erase(temp);
         }
 ​
         return ret;
     }
 ​
     template<class T>
     void list<T>::clear()
     {
         erase(begin(), end());
     }
 ​
     /***********************基本功能实现完毕,深入拓展************************/
     
     // 有参构造,和两个辅助函数ctorAux
     template<class T>
     inline list<T>::list(size_type n, const value_type& val)
     {
         ctorAux(n, val, std::is_integral<value_type>());
     }
 ​
     template<class T>
     template<class InputIterator>
     inline list<T>::list(InputIterator first, InputIterator last)
     {
         ctorAux(first, last, std::is_integral<InputIterator>());
     }
 ​
     template<class T>
     inline void list<T>::ctorAux(size_type n, const value_type& val, std::true_type)
     {
         head.p = newNode(); // 虚假节点dummy
         tail.p = head.p;
 ​
         while (n--)
             push_back(val);
     }
 ​
     // 实现插入一段list
     template<class T>
     template<class InputIterator>
     inline void list<T>::ctorAux(InputIterator first, InputIterator last, std::false_type)
     {
         head.p = newNode(); // 虚假节点dummy
         tail.p = head.p;
 ​
         for (; first != last; ++first)
         {
             push_back(*first);
         }
     }
 ​
     // 拷贝构造函数 浅拷贝
     template<class T>
     list<T>::list(const list& l)
     {
         head.p = newNode();
         tail.p = head.p;
 ​
         for (auto node = l.head.p; node != l.tail.p; ++node)
         {
             push_back(node->data);
         }
     }
 ​
     template<class T>
     typename list<T>& list<T>::operator=(const list& l) 
     {
         if (this != &l)
         {
             list(l).swap(*this);    // 先使用L2(L1)构造函数,然后再进行swap进行copy
         }
         return *this;
     }
 ​
     template<class T>
     void list<T>::swap(list& x)
     {
         mySTL::swap(head.p, x.head.p);  // 值交换
         mySTL::swap(tail.p, x.tail.p);
     }
 ​
     
 ​
     template<class T>
     void swap(list<T>& x, list<T>& y)
     {
         x.swap(y);
     }
 ​
     // insert多项插入,两个辅助函数insert_aux
     template<class T>
     inline void list<T>::insert(iterator position, size_type n, const value_type& val)
     {
         insert_aux(position, n, val, typename std::is_integral<value_type>::type());
     }
 ​
     template<class T>
     template<class InputIterator>
     inline void list<T>::insert(iterator position, InputIterator first, InputIterator last)
     {
         insert_aux(position, first, last, typename std::is_integral<InputIterator>::type());
     }
 ​
     
 ​
     template<class T>
     inline void list<T>::insert_aux(iterator position, size_type n, const T& val, std::true_type)
     {
         for (auto i = n; i != 0; --i)
         {
             position = insert(position, val);
         }
     }
 ​
     template<class T>
     template<class InputIterator>
     inline void list<T>::insert_aux(iterator position, InputIterator first, InputIterator last, std::false_type)
     {
         for (--last; first != last; --last)     // last为end,没有元素值,需要变为back
         {
             position = insert(position, *last); // 逆序插入,insert返回为插入的元素地址
         }
         insert(position, *last);
     }
 ​
     /***********************丰富构造函数、插入函数,接下来进行功能拓展************************/
     // 合并两个list 
     template<class T>
     inline void list<T>::splice(iterator position, list& x)
     {
         this->insert(position, x.begin(), x.end());
         x.head.p = x.tail.p;
     }
 ​
     template<class T>
     inline void list<T>::splice(iterator position, list& x, iterator first, iterator last)
     {
         if (first.p == last.p) return;
 ​
         auto tailNode = last.p->prev;
         // list x的处理,合并后删除对应元素
         if (x.head.p == first.p)
         {
             x.head.p = last.p;
             x.head.p->prev = nullptr;
         }
         else
         {
             first.p->prev->next = last.p;
             last.p->prev = first.p->prev;
         }
 ​
         // 开始合并
         if (position.p == head.p)
         {
             first.p->prev = nullptr;
             tailNode->next = head.p;
             head.p->prev = tailNode;
             head.p = first.p;
         }
         else
         {
             position.p->prev->next = first.p;
             first.p->prev = position.p->prev;
 ​
             tailNode->next = position.p;
             position.p->prev = tailNode;
         }
     }
 ​
     // 指定位置元素的合并
     template<class T>
     inline void list<T>::splice(iterator position, list& x, iterator i)
     {
         auto next = i;
         this->splice(position, x, i, ++next);
     }
 ​
     // 排序合并两个list 
     template<class T>
     void list<T>::merge(list& x)
     {
         auto it1 = begin(), it2 = x.begin();
         while (it1 != end() && it2 != x.end())
         {
             if (*it1 <= *it2)
             {
                 ++it1;
             }
             else
             {
                 auto temp = it2++;
                 this->splice(it1, x, temp);
             }
         }
 ​
         if (it1 == end())
         {
             this->splice(it1, x, it2, x.end());
         }
     }
 ​
     template<class T>
     template<class Compare>
     inline void list<T>::merge(list& x, Compare comp)
     {
         auto it1 = begin(), it2 = x.begin();
         while (it1 != end() && it2 != x.end())
         {
             if (comp(*it2, *it1))
             {
                 auto temp = it2++;
                 this->splice(it1, x, temp);             
             }
             else
             {
                 ++it1;
             }
         }
 ​
         if (it1 == end())
         {
             this->splice(it1, x, it2, x.end());
         }
     }
 ​
     // 从list删除元素 或 指定条件删除
     template<class T>
     inline void list<T>::remove(const value_type& val)
     {
         for (auto it = begin(); it != end();)
         {
             if (*it == val)
                 it = erase(it);
             else
                 ++it;
         }
     }
 ​
     template<class T>
     template<class Predicate>
     inline void list<T>::remove_if(Predicate pred)
     {
         for (auto it = begin(); it != end();) 
         {
             if (pred(*it))
                 it = erase(it);
             else
                 ++it;
         }
     }
 ​
     //  删除list中相邻重复的元素
     template<class T>
     void list<T>::unique()
     {
         nodePtr curNode = head.p;
 ​
         while (curNode != tail.p->prev)
         {
             nodePtr nextNode = curNode->next;
 ​
             if (curNode->data == nextNode->data)
             {
                 if (nextNode == tail.p)
                 {
                     curNode->next = nullptr;
                     tail.p = curNode;
                 }
                 else
                 {
                     curNode->next = nextNode->next;
                     nextNode->next->prev = curNode;
                 }
                 deleteNode(nextNode);
             }
             else
             {
                 curNode = nextNode;
             }
         }
     }
 ​
     template<class T>
     template<class BinaryPredicate>
     inline void list<T>::unique(BinaryPredicate binary_pred)
     {
     }
 ​
     // 给list排序 
     template<class T>
     void list<T>::sort()
     {
         sort(mySTL::less<T>());
     }
 ​
     template<class T>
     template<class Compare>
     inline void list<T>::sort(Compare comp)
     {
         // 侯捷书说是:快速排序, 个人认为更像是归并排序
         // 空链表和只有一个元素不进行操作
         if (empty() || head.p->next == tail.p) return;
 ​
         // 一些新的lists,作为中介数据存放区
         list carry;         // 临时变量
         list counter[64];   // 可以储存2^64 - 1数据
         int fill = 0;       // 数据放置了小于2^fill - 1个数据
         
         while (!empty())
         {
             carry.splice(carry.begin(), *this, begin());    // carry每次获取一个数据
             int i = 0;
 ​
             while (i < fill && !counter[i].empty())
             {
                 counter[i].merge(carry, comp);              // 归并
                 carry.swap(counter[i++]);                   // 数据临时存放至carry
             }
 ​
             carry.swap(counter[i]);
 ​
             if (i == fill)                                  // 数据增加最多2^fill - 1个数据
                 ++fill;
         }
         // 归并所有项
         for (int i = 1; i != fill; ++i)
         {
             counter[i].merge(counter[i - 1], comp);
         }
         // 返回原先的变量
         swap(counter[fill - 1]);
         
     }
 ​
     //  把list的元素倒转
     template<class T>
     typename list<T>::reverse_iterator list<T>::rbegin()
     {
         return reverse_iterator(tail);
     }
 ​
     template<class T>
     typename list<T>::reverse_iterator list<T>::rend() {
         return reverse_iterator(head);
     }
 ​
     template<class T>
     void list<T>::reverse() //采用尾插法
     {
         if (empty() || head.p->next == tail.p) return;
         auto curNode = head.p;
         head.p = tail.p->prev;
         head.p->prev = nullptr;
 ​
         do {
             auto nextNode = curNode->next;
             
             curNode->next = head.p->next;
             head.p->next->prev = curNode;
             curNode->prev = nextNode;
 ​
             // 更新
             head.p->next = curNode;         
             curNode = nextNode;
 ​
         } while (curNode != head.p);
 ​
     }
 ​
     // 拓展 == 、!=
     template<class T>
     bool operator==(const list<T>& lhs, const list<T>& rhs)
     {
         auto node1 = lhs.head.p, node2 = rhs.head.p;
         while ( node1 != lhs.tail.p && node2 != rhs.tail.p ) 
         {
             if (node1->data != node2->data)
                 break;
             node1 = node1->next, node2 = node2->next;
         }
         if (node1 == lhs.tail.p && node2 == rhs.tail.p)
             return true;
         return false;
     }
 ​
     template<class T>
     bool operator!=(const list<T>& lhs, const list<T>& rhs)
     {
         return !(lhs == rhs);
     }
 ​
 }
 #endif

sort案例解析

sort算法流程:

stl_list_test.h

 
#ifndef _LIST_TEST_H_
 #define _LIST_TEST_H_
 ​
 #include "../p2_STL_Source/stl_list.h"
 #include <list>
 ​
 #include <cassert>
 #include <functional>
 #include <string>
 #include <random>
 #include <time.h>
 ​
 namespace mySTL {
     namespace listTest {
         template<class T>
         using stdL = std::list<T>;
         template<class T>
         using myL = mySTL::list<T>;
 ​
         template<class T>
         void stdPrint(std::list<T>& l);
         template<class T>
         void myPrint(mySTL::list<T>& l);
         void test01();  // 完成无参构造,和size、emptys push pop功能测试,继续拓展
         void test02();  // 完成insert erase clear 完成基本功能
         void test03();  // 深入拓展,有参构造 拷贝构造 多项insert
         void test04();  // splice merge
         void test05();  // remove remove_if unique
         void test06();  // sort reverse
     }
 }
 ​
 #endif

stl_list_test.cpp

这个测试函数你可以自己写

 #include "stl_list_test.h"
 ​
 using namespace std;
 ​
 namespace mySTL {
     namespace listTest {
         template<class T>
         void stdPrint(std::list<T>& l)
         {
             cout << "stdSTL: ";
             for (auto i = l.begin(); i != l.end(); i++)
             {
                 
                 cout << *i <<"  ";
             }
             cout << endl;
         }
         template<class T>
         void myPrint(mySTL::list<T>& l)
         {
             cout << "mySTL:  ";
             for (auto i = l.begin(); i != l.end(); i++)
             {
                 cout << *i << "  ";
             }
             cout << endl;
         }
 ​
         void test01()
         {
             stdL<int> l1;
             myL<int> l2;
             cout << "-------------create test----------" << endl;
             cout << "l1: " << l1.size() << "\tl2: " << l2.size() << endl;
             cout << "l1: " << l1.empty() << "\tl2: " << l2.empty() << endl;
 ​
             l1.push_front(2);
             l2.push_front(3);
             l1.push_back(10);
             l2.push_back(12);
             l1.push_back(100);
             l2.push_back(112);
             cout << "-------------push test----------" << endl;
             cout << "l1: " << l1.front() << "\tl2: " << l2.front() << endl;
             cout << "l1: " << l1.size() << "\tl2: " << l2.size() << endl;
             cout << "l1: " << l1.back() << "\tl2: " << l2.back() << endl;
 ​
 ​
             l1.pop_front();
             l2.pop_front();
             l1.pop_back();
             l2.pop_back();
             cout << "-------------pop test----------" << endl;
             cout << "l1: " << l1.front() << "\tl2: " << l2.front() << endl;
             cout << "l1: " << l1.size() << "\tl2: " << l2.size() << endl;
             cout << "l1: " << l1.back() << "\tl2: " << l2.back() << endl;
 ​
             stdL<string> l3;
             myL<string> l4;
             
             cout << "-------------string type test----------" << endl;
             cout << boolalpha << "l1: " << l3.empty() << "\tl2: " << l4.empty() << endl;
             l3.push_back("xfy");
             l4.push_back("xfy");
             cout << "l3: " << l3.front() << "\tl4: " << l4.front() << endl;
 ​
             cout << "-------------string type 2 test----------" << endl;
             std::string arr[] = { "1", "2", "3" };
             myL<std::string> l(std::begin(arr), std::end(arr));
             l.front() = "front";
             l.back() = "back";
 ​
             myPrint(l);
         }
         void test02()
         {
             stdL<int> l1;
             myL<int> l2;
             l1.push_front(2);
             l2.push_front(3);
             l1.push_back(10);
             l2.push_back(12);
             l1.push_back(100);
             l2.push_back(112);
 ​
             cout << "-------------print test----------" << endl;
             stdPrint(l1);
             myPrint(l2);
 ​
             cout << "-------------insert test----------" << endl;
             auto tmpL1 = l1.begin();
             l1.insert(++tmpL1, 20);
             tmpL1 = l1.end();
             l1.insert(--tmpL1, 20);
             stdPrint(l1);
             auto tmpL2 = l2.begin();
             l2.insert(++tmpL2, 30);
             tmpL2 = l2.end();
             l2.insert(--tmpL2, 30);
             myPrint(l2);
 ​
             cout << "l1: " << l1.size() << "\tl2: " << l2.size() << endl;
 ​
             cout << "-------------erase test----------" << endl;
             l1.insert(--tmpL1, 20);
             l1.insert(--tmpL1, 60);
             l1.insert(--tmpL1, 70);
             stdPrint(l1);
             l2.insert(--tmpL2, 40);
             l2.insert(--tmpL2, 50);
             l2.insert(--tmpL2, 30);
             myPrint(l2);
             cout << "l1: " << l1.size() << "\tl2: " << l2.size() << endl;
 ​
             tmpL1 = l1.begin();
             tmpL2 = l2.begin();
 ​
             l1.erase(++tmpL1);
             l2.erase(++tmpL2);
             stdPrint(l1);           
             myPrint(l2);
             cout << "l1: " << l1.size() << "\tl2: " << l2.size() << endl;
 ​
             l1.erase(++l1.begin(), --l1.end());
             l2.erase(++l2.begin(), --l2.end());
             stdPrint(l1);
             myPrint(l2);
             cout << "l1: " << l1.size() << "\tl2: " << l2.size() << endl;
 ​
             cout << "-------------clear test----------" << endl;
             l1.clear();
             l2.clear();
             stdPrint(l1);
             myPrint(l2);
             cout << "l1: " << l1.size() << "\tl2: " << l2.size() << endl;
         }
 ​
         void test03()
         {
             stdL<int> l1(10, 6);
             myL<int> l2(10, 7);
 ​
             cout << "-------------param constructor test----------" << endl;
             stdPrint(l1);
             myPrint(l2);
 ​
             cout << "-------------copy constructor test----------" << endl;
             stdL<int> l3(l1.begin(), l1.end());
             myL<int> l4(l2.begin(), l2.end());
             stdPrint(l3);
             myPrint(l4);
 ​
             cout << "------------- copy2 test----------" << endl;
             auto l5(l1);
             auto l6(l2);
             stdPrint(l5);
             myPrint(l6);
 ​
             cout << "------------- copy3( = ) test----------" << endl;
             auto l7 = l1;
             auto l8 = l2;
             stdPrint(l7);
             myPrint(l8);
 ​
             cout << "------------- insert1 test----------" << endl;
             l7.insert(++l7.begin(), 3, 3);
             l8.insert(++l8.begin(), 3, 4);
             stdPrint(l7);
             myPrint(l8);
 ​
 ​
 ​
             cout << "------------- insert2 test----------" << endl;
             stdL<int> l9(5, 9);
             myL<int> l10(5, 8);
             l7.insert(++l7.begin(), l9.begin(), l9.end());
             l8.insert(++l8.begin(), l10.begin(), l10.end());
             stdPrint(l7);
             myPrint(l8);
 ​
         }
 ​
         void test04()
         {
             cout << "------------- splice test----------" << endl;
             std::string arr1[] = { "1", "2", "3" };
             myL<std::string> l1(std::begin(arr1), std::end(arr1));
 ​
             std::string arr2[] = { "4", "5", "6", "a", "b", "c" };
             myL<std::string> l2(std::begin(arr2), std::end(arr2));
 ​
             
             
             cout << "------------- raw print test----------" << endl;
             myPrint(l1);
             myPrint(l2);
             cout << "------------- splice1 print test----------" << endl;
             l1.splice(l1.end(), l2, l2.begin());
             myPrint(l1);
             myPrint(l2);
             cout << "------------- splice2 print test----------" << endl;
             auto tmp = l2.begin();
             for (int i = 3; i >= 0; --i) ++tmp;
             l1.splice(l1.end(), l2, l2.begin(), tmp);
             myPrint(l1);
             myPrint(l2);
             cout << "------------- splice3 print test----------" << endl;
             l1.splice(l1.end(), l2);
             myPrint(l1);
             myPrint(l2);
 ​
             cout << "------------- merge  test----------" << endl;
             myL<int> l3, l4;
             myL<int> l5, l6;
             srand(time(NULL));
             for (int i = 0; i < 10; ++i)
             {
                 int tmp = rand() % 10 + 1;
                 l3.push_back(tmp);
                 l5.push_back(tmp);
             }
             for (int i = 0; i < 10; ++i)
             {
                 int tmp = rand() % 10 + 1;
                 l4.push_back(tmp);
                 l6.push_back(tmp);
             }
             
             cout << "------------- raw print test----------" << endl;
             myPrint(l3);
             myPrint(l4);
             cout << "------------- merge1  test----------" << endl;
             l3.merge(l4);
             myPrint(l3);
             myPrint(l4);
 ​
             cout << "------------- raw print test----------" << endl;
             myPrint(l5);
             myPrint(l6);
             cout << "------------- merge2 comp  test----------" << endl;
             l5.merge(l6, [](int x, int y) {return x > y; });
             myPrint(l5);
             myPrint(l6);
             
         }
 ​
         void test05()
         {
             int arr[] = { 0, 0, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 7, 8, 8, 9, 11 };
             stdL<int> l1(std::begin(arr), std::end(arr));
             myL<int> l2(std::begin(arr), std::end(arr));
             stdL<int> l3(std::begin(arr), std::end(arr));
             myL<int> l4(std::begin(arr), std::end(arr));
 ​
             cout << "------------- raw  test----------" << endl;
             stdPrint(l1);
             myPrint(l2);
             cout << "------------- remove  test----------" << endl;
             l1.remove(4);
             l2.remove(4);
             stdPrint(l1);
             myPrint(l2);
 ​
             cout << "------------- remove_if  test----------" << endl;
             l1.remove_if([](int x) {return x % 2; });
             l2.remove_if([](int x) {return x % 2; });
             stdPrint(l1);
             myPrint(l2);
 ​
             cout << "------------- raw  test----------" << endl;
             stdPrint(l3);
             myPrint(l4);
             //cout << "l3: " << l3.size() << "\tl4: " << l4.size() << endl;
             cout << "------------- unique  test----------" << endl;
             l3.unique();
             l4.unique();
             stdPrint(l3);
             myPrint(l4);
 ​
         }
 ​
         void test06()
         {
         
             
             myL<int> l1;
             srand(time(NULL));
             for (int i = 0; i < 10; ++i)
             {
                 int tmp = rand() % 100 + 1;
                 l1.push_back(tmp);
             }
             cout << "------------- raw  test----------" << endl;
             myPrint(l1);
             cout << "------------- sort  test----------" << endl;
             l1.sort();
             myPrint(l1);
             cout << "------------- sort compare  test----------" << endl;
             l1.sort([](int x, int y) {return x > y; });
             myPrint(l1);
             cout << "------------- reverse  test----------" << endl;
             l1.reverse();
             myPrint(l1);
         }
     }
 }

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值