这个list最大问题在于结点没有形成闭环,且模板参数没有分配器
list.h
#ifndef _LIST_H_
#define _LIST_H_
/*这个list没有形成一个闭环
第16行、第33行、第49行。第72行,第73行
第112行。list没有分配器*/
#include "Allocator.h"
#include "Iterator.h"
#include "ReverseIterator.h"
#include "UninitializedFunctions.h"
#include <type_traits>
namespace TinySTL{
template<class T>
class list;
namespace Detail{
//为什么要再用一个命名空间
//the class of node
template<class T>
struct node{
T data;
node *prev;
node *next;
list<T> *container;
node(const T& d, node *p, node *n, list<T> *c):
data(d), prev(p), next(n), container(c){
}
bool operator ==(const node& n){
return data == n.data && prev == n.prev && next == n.next && container == n.container;
}
};
//the class of list iterator
template<class T>
struct listIterator :public iterator<bidirectional_iterator_tag, T>{
//外部的public什么意思?
template<class T>
friend class list;//list可以使用listIterator
public:
typedef node<T>* nodePtr;
nodePtr p;
public:
explicit listIterator(nodePtr ptr = nullptr) :p(ptr){
}
listIterator& operator++();//前缀
listIterator operator++(int);//后缀
listIterator& operator --();
listIterator operator --(int);
T& operator *(){
return p->data; }//解引用
T* operator ->(){
return &(operator*()); }
/*
T* operator ->(){ return &(operator*()); }
当被调用时,例如
list<T>::iterator it=s.begin();
it->data;
相当于调用 it.operator->()->data;
首先调用operator*()返回的是data的引用,然后对data取地址,但是这里的地址实际上也是结构体的地址。
残余问题:如果说it->相当于返回it.operator->()但此时返回的是一个地址,后面的->从何而来
*/
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);
};
}//end of namespace
//the class of list
template<class T>
class list{
template<class T>
friend struct listIterator;//互为友元?
private:
typedef allocator<Detail::node<T>> nodeAllocator;//分配器?
typedef Detail::node<T> *nodePtr;//是不是错了,应该是typedef Detail::node<T>* nodePtr;
public:
typedef T value_type;
typedef Detail::listIterator<T> iterator;//迭代器类对象。迭代器类设计--包含一个指针变量:node结构体的地址
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;
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();
//迭代器相关函数
iterator begin();
iterator end();
const_iterator begin()const;
const_iterator end()const;
reverse_iterator rbegin();
reverse_iterator rend();
//接口函数
void push_front(const value_type& val);
void pop_front();
void push_back(const value_type& val);
void pop_back();
bool empty()const{
return head == tail; }
size_type size()const;
reference front(){
return (head.p->data); }
reference back(){
return (tail.p->prev->data); }
iterator insert(iterator position, const value_type& val);
void insert(iterator position, size_type n, const value_type& val);//这个insert和下个insert为什么没有返回值
template <class InputIterator>
void insert(iterator position, InputIterator first, InputIterator last);
iterator erase(iterator position);
iterator erase(iterator first, iterator last);
void swap(list& x);
void clear();
void splice(iterator position, list& x);
void splice(iterator position, list& x, iterator i);
void splice(iterator position, list& x, iterator first, iterator last);
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 merge(list& x);
template <class Compare>
void merge(list& x, Compare comp);
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);
nodePtr newNode(const T& val = T());
void deleteNode(nodePtr p);
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);
const_iterator changeIteratorToConstIterator(iterator& it)const;
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);
};//end of List
}
#include "Detail\List.impl.h"
#endif
list.cpp
#ifndef _LIST_IMPL_H_
#define _LIST_IMPL_H_
/*
本list是一个双向非环链表,head.prev=tail.next=NULL;
第97行常迭代器转换问题,第129行,第187行
第275行unique函数错误,第317行是否要补充条件this!=x。x置空的必要性?
第323行,修改splice(fisrt,last)和splice(i)。让splice(first,last)调用i
第393行。
*/
namespace TinySTL{
namespace Detail{
//重载运算符
template<class T>
listIterator<T>& listIterator<T>::operator++(){
p = p->next;
return *this;
}
template<class T>
listIterator<T> listIterator<T>::operator++(int){
auto res = *this;
++*this;
return res;
}
template<class T>
listIterator<T>& listIterator<T>::operator --(){
p = p->prev;
return *this;
}
template<class T>
listIterator<T> listIterator<T>::operator --(int){
auto res = *this;
--*this;
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);
}
}//end of Detail namespace
//构造、复制、析构函数
template<class T>
list<T>::list(){
//空链表
head.p = newNode();
tail.p = head.p;
}
template<class T>
list<T>::list(size_type n, const value_type& val = value_type()){
//构建n个默认值的链表
ctorAux(n, val, std::is_integral<value_type>());//萃取,要求value_type是泛整数类型
}
template<class T>
template <class InputIterator>
list<T>::list(InputIterator first, InputIterator last){
//根据区间创建链表
ctorAux(first, last, std::is_integral<InputIterator>());//要求迭代器非泛整型
}
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 = node->next)
push_back(node->data);
}
template<class T>
list<T>& list<T>::operator = (const list& l){
//重载=
if (this != &l){
//不使用拷贝构造,因为这里已经有对象了,拷贝构造是在没有对象前提下
list(l).swap(*this);//等价于temp=list(l);temp.swap(*this);
}
return *this;
}
template<class T>
list<T>::~list(){
//析构
for (; head != tail;){
//依次销毁各个节点
auto temp = head++;
nodeAllocator::destroy(temp.p);
nodeAllocator::deallocate(temp.p);
}
nodeAllocator::deallocate(tail.p);
}
//迭代器相关函数
template<class T>
typename list<T>::iterator list<T>::begin(){
return head;
}
template<class T>
typename list<T>::iterator list<T>::end(){
return tail;
}
template<class T>
typename list<T>::const_iterator list<T>::changeIteratorToConstIterator(iterator& it)const{
//转换常迭代器
/*需要转换的内容:迭代器内容和迭代器本身类型
迭代器内容包括node指针,list指针*/
using nodeP = Detail::node<const T>*;//等价于typedef Detai::node<const T>* nodeP;
auto temp = (list<const T>*const)this;//强制转换为指针常量,原本为list<T>*,这里转换为list<const T>*const
auto ptr = it.p;//取迭代器内容,typedef node<T>* nodePtr;nodePtr p;
Detail::node<const T> node(ptr->data, (nodeP)(ptr->prev), (nodeP)(ptr->next), temp);//强制转换;ptr->data本来就是const
return const_iterator(&node);//listIterator<const T>迭代器本身类型
}
template<class T>
typename list<T>::const_iterator list<T>::begin()const{
auto temp = (list*const)this;//这里为什么不用list<const T>*const
return changeIteratorToConstIterator(temp->head);
}
template<class T>
typename list<T>::const_iterator list<T>::end()const{
auto temp = (list*const)this;
return changeIteratorToConstIterator(temp->tail);
}
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>::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>
void list<T>::push_back(const value_type& val){
//尾插
auto node = newNode();
(tail.p)->data = val;
(tail.p)->next = node;
node->prev = tail.p;
tail.p = node;
}
template<class T>
void list<T>::pop_back(){
//尾删,是否要判空
auto newTail = tail.p->prev;
newTail->next = nullptr;
deleteNode(tail.p);
tail.p = newTail;
}
template<class T>
typename list<T>::size_type list<T>::size()const{
//求长度
size_type length = 0;
for (auto h = head; h != tail; ++h)
++length;
return length;
}
template<class T>
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()){
auto ret = position;
push_back(val);
return ret;
}
auto node = newNode(val);//更新前后结点
auto prev = position.p->prev;//记录pos前结点
node->next = position.p;//设置新节点的后续节点
node->prev = prev;//设置新节点的前结点
prev->next = node;//设置前结点的后结点
position.p->prev = node;//设置后结点的前结点
return iterator(node);//封装为迭代器
}
template<class T>
void list<T>::insert(iterator position, size_type n, const value_type& val){
//插入n个值
nsert_aux(position, n, val, typename std::is_integral<InputIterator>::type());//错误萃取内容是否应该为size_type
}
template<class T>
template<clas InputIterator>
void list<T>::insert(iterator position,InputIterator first,InputIterator last){
//插入区间
insert_aux(position,first,last,typename std::is_integral<InputIterator>::type());
}
template<class T>
typename list<T>::iterator list<T>::erase(iterator position){
//擦除指定位置,并返回next位置的迭代器
if(position==head){
pop_front();
return head;
}
else{
auto prev=position.p-prev;
prev->next=position.p->next;
postion.p->next->prev=prev;
deleteNode(position.p);
return iterator(prev->next);
}
}
template<class T>
typename list<T>::iterator lsit<T>::erase(iterator firsr,iterator last){
//擦除区间
typename list<T>::iterator res;
for(;first!=last;){
auto temp=first++;
res=erase(temp);
}
return res;
}
template<class>
void list<T>::clear(){
//清空
erase(begin(),end());
}
template<class T>
void list<T>::reverse(){
//反转链表
if (empty() || head.p->next == tail.p) return;//空链表或者只有一个元素
auto curNode = head.p;//保存头结点
head.p = tail.p->prev;//将头结点设定为尾结点tail.prev
head.p->prev = nullptr;//设定头结点结束
do{
auto nextNode=curNode->next;
head.p->next->prev=curNode;
cureNode->next=head.p->next;
head.p->next=curNode;
cureNode->prev=head.p;
curNode=nextNode;
} while (curNode != head.p);//此过程中,尾结点没有发生变化
}
template<class T>
void list<T>::remove(const value_type& val){
//移除指定值结点
for (auto it = begin(); it != end();){
if (*it == val)
it = erase(it);//如果移除,则erase的返回值为下一个结点
else
++it;
}
}
template<class T>
template <class Predicate>//谓语表达式
void list<T>::remove_if(Predicate pred){
//移除指定条件结点
for (auto it = begin(); it != end();){
if (pred(*it))
it = erase(it);
else
++it;
}
}
template<class T>
void list<T>::swap(list& x){
//交换2个链表
TinySTL::swap(head.p, x.head.p);//实际上也就是交换两个链表的头结点和尾结点
TinySTL::swap(tail.p, x.tail.p);
}
template<class T>
void swap(list<T>& x, list<T>& y){
x.swap(y);//重载
}
template<class T>
void list<T>::unique(){
//删除链表中相邻重复元素,因此如果要去除链表中所有重复元素,首先要排序
nodePtr curNode = head.p;//既然有迭代器,就该用迭代器操作
while (curNode != tail.p){
nodePtr nextNode = curNode->next;
if (curNode->data == nextNode->data){
if (nextNode == tail.p){
//nextNode既然有元素,怎么可能等于tail?
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>
void list<T>::unique(BinaryPredicate binary_pred){
//按谓语表达式删除相邻元素
nodePtr curNode = head.p;
while (curNode != tail.p){
nodePtr nextNode = curNode->next;
if (binary_pred(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>
void list<T>::splice(iterator position, list& x){
//把(list)x的所有元素都拼接到this上,前提条件x和this不同
this->insert(position, x.begin(), x.end());
x.head.p = x.tail.p;//清空
}
template<class T>
void list<T>::splice(iterator position, list& x, iterator first, iterator last){
//将x的一部分拼接到指定位置
if (first.p == last.p) return;
auto tailNode = last.p->prev;
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>
void list<T>::splice(iterator position, list& x, iterator i){
auto next = i;
this->splice(position, x, i, ++next);
}
template<class T>
void list<T>::merge(list& x){
//合并list,前提两个list均已排序
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>
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());
}
}
template <class T>
bool operator== (const list<T>& lhs, const list<T>& rhs){
//重载==
auto node1 = lhs.head.p, node2 = rhs.head.p;
for (; node1 != lhs.tail.p && node2 != rhs.tail.p; node1 = node1->next, node2 = node2->next){
if (node1->data != node2->data)
break;//可以直接返回false
}
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);
}
template<class T>
void list<T>::sort(){
//排序
sort(TinySTL::less<T>());//默认递增排序
}
template<class T>
template <class Compare>
void list<T>::sort(Compare comp){
//含谓语条件排序
if (empty() || head.p->next == tail.p)
return;
//快排。最坏复杂度不如归并,因此可以使用归并排序
list<T> carry;
list<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, comp);
carry.swap(counter[i++]);
}
carry.swap(counter[i]);
if (i == fill)
++fill;
}
for (int i = 0; i != fill; ++i){
counter[i].merge(counter[i - 1], comp);
}
swap(counter[fill - 1]);
}
//内部封装函数
template<class T>
void list<T>::insert_aux(iterator position, size_type n, const T& val, std::true_type){
//插入n个值
for (auto i = n; i != 0; --i){
position = insert(position, val);//insert返回的是插入后的结点
}
}
template<class T>
template<class InputIterator>
void list<T>::insert_aux(iterator position, InputIterator first, InputIterator last, std::false_type){
//插入一个区间
for (--last; first != last; --last){
position = insert(position, *last);
}
insert(position, *last);
}
template<class T>
typename list<T>::nodePtr list<T>::newNode(const T& val = T()){
//创建属于容器list的新结点
nodePtr res = nodeAllocator::allocate();//分配内存
nodeAllocator::construct(res, Detail::node<T>(val, nullptr, nullptr, this));//建立结点
return res;
}
template<class T>
void list<T>::deleteNode(nodePtr p){
//删除结点
p->prev = p->next = nullptr;
nodeAllocator::destroy(p);//销毁
nodeAllocator::deallocate(p);//释放
}
template<class T>
void list<T>::ctorAux(size_type n, const value_type& val, std::true_type){
//建立一个n个val的链表
head.p = newNode();//先创建一个结束结点tail
tail.p = head.p;
while (n--)
push_back(val);//尾插法建立
}
template<class T>
template <class InputIterator>
void list<T>::ctorAux(InputIterator first, InputIterator last, std::false_type){
//建立一个区间的链表
head.p = newNode();
tail.p = head.p;
for (; first != last; ++first)
push_back(*first);
}
}
#endif