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);
}
}
}