List的底层数据结构的实现就是双向循环链表,下面给出结点的封装,简易迭代器的封装,还有头指针的封装和相关功能的实现和测试的结果
1.结点的封装代码如下:
template<class T>
struct ListNode//定义结点的类
{
public:
ListNode<T> *_pre;//后指针
ListNode<T> *_next;//前指针
T _data;//储存数据
public:
ListNode(const T& data = T())//构造函数
:_pre(0)
, _next(0)
, _data(data){}
};
2.给出简易迭代器的封装代码。其实迭代器就是一个可以指向结点的指针
template<class T,class Ref,class Src>//迭代器的类
class Iterator
{
public:
ListNode<T>* _pCur;
public:
Iterator()//构造函数
: _pCur(0){}
Iterator(ListNode<T>* pCur)//有参数的构造函数
:_pCur(pCur){}
Iterator(const Iterator<T,Ref,Src>& s)//拷贝构造函数
:_pCur(s._pCur){}
Ref& operator*()
{
return _pCur->_data;
}
Src* operator->()
{
return &(_pCur->_data);
}
Iterator < T, Ref, Src > operator++(int)//后置++
{
Iterator<T, Ref, Src> temp(*this);
_pCur = _pCur->_next;
return temp;
}
Iterator < T, Ref, Src > operator++()//前置++
{
_pCur = _pCur->_next;
return *this;
}
Iterator < T, Ref, Src > operator--()//前置--
{
_pCur = _pCur->_pre;
return *this;
}
Iterator < T, Ref, Src > operator--(int)//后置--
{
Iterator < T, Ref, Src > temp(*this)
_pCur = _pCur->_pre;
return temp;
}
bool operator!=(const Iterator < T, Ref, Src >& s)
{
return _pCur != s._pCur;
}
bool operator==(const Iterator < T, Ref, Src >& s)
{
return _pCur == s->_pPcur;
}
};
因为迭代器其实就是指向结点的指针,既然是指针所以其对象就要有指针的相关功能,所以给出了上述的运算符重载函数
3.下面给出头指针的封装和具体的迭代器和结点的结合使用,还有相关的功能的实现
//可以直接在里面使用迭代器
template<class T>
class ListHead//封装头指针的类
{
public:
ListNode<T> *_head;//定义头指针成员变量,指向结点的指针
typedef Iterator<T, T&, T*> Iterator;//在这个类中定义迭代器
public:
ListHead()//无参构造函数
:_head(new ListNode<T>)//给头结点开辟空间
{
_head->_pre = _head;
_head->_next = _head;
}
ListHead(const T*array, size_t size)//有参数的构造函数
:_head(new ListNode<T>)//开辟头结点
{
_head->_next = _head;
_head->_pre = _head;
for (size_t i =0 ; i < size; i++)
{
PushBack(array[i]);
}
}
/*List(const List& l);
List& operator=(const List& l);*/
~ListHead()
{
Clear();
delete []_head;
_head = NULL;
}
void PushBack(const T& data)
{
ListNode<T> *NewNode = new ListNode<T>(data);
if (Empty())
{
_head->_next = NewNode;
NewNode->_next = _head;
NewNode->_pre = _head;
_head->_pre = NewNode;
}
else
{
ListNode<T>* pLast = _head->_pre;//找到最后一个结点
NewNode->_next = _head;
NewNode->_pre = pLast;
pLast->_next = NewNode;
_head->_pre = NewNode;
}
}
void PushFront(const T& data)
{
ListNode<T> *NewNode = new ListNode<T>(data);
if (Empty())
{
_head->_next = NewNode;//头指针指向第一个结点
NewNode->_next = _head;//第一个结点next指向头指针
NewNode->_pre = _head;//第一个结点pre向头指针
_head->_pre = NewNode;//头指针pre指向第一个结点
}
else
{
NewNode->_next = _head->_next;
NewNode->_pre = _head;
_head->_next->_pre = NewNode;
_head->_next = NewNode;
}
}
void PopFront()//头删除
{
if (!Empty())
{
ListNode<T> *p = _head->_next;//保存第一个结点
_head->_next = p->_next;
p->_next->_pre = _head;
delet p;
}
}
void PopBack()//尾删除
{
if (!Empty())
{
ListNode<T> *p = _head->_pre->_pre;//保存倒数第二个结点
delete p->_next;//销毁最后一个结点
p->_next = _head;
_head->_pre = p;
}
}
Iterator Begin()//返回第一个结点的地址
{
return Iterator(_head->_next);
}
Iterator End()//返回最后一个结点的地址
{
return Iterator(_head->_pre);
}
Iterator Insert(Iterator pos, const T& data)//指定位置插入,返回插入的结点
{
ListNode<T>* pNewNode = new ListNode<T>(data);
pNewNode->_next = pos._pCur;
pos._pCur->_pre->_next = pNewNode;
pNewNode->_pre = pos._pCur->_pre;
pos._pCur->_pre = pNewNode;
return Iterator(pNewNode);
}
Iterator Erase(Iterator pos)//指定位置删除,返回删除的下一个结点
{
ListNode<T> *src = pos._pCur->_next;
pos._pCur->_pre->_next = pos._pCur->_next;
pos._pCur->_next->_pre = pos._pCur->_pre;
delete pos._pCur;
pos._pCur = NULL;
return src;
}
bool Empty()const
{
return _head->_pre == _head;//只有一个头结点
}
size_t Size()const
{
ListNode<T> *dest = _head->_next;//标记第一个结点
size_t count = 0;
while (dest!= _head)
{
dest = dest->_next;
count++;
}
return count;
}
T& Front()
{
return _head->_next->data;
}
const T& Front()const
{
return _head->_next->data;
}
T& Back()
{
return _head->_pre->data;
}
const T& Back()const
{
return _head->_pre->data;
}
void Clear()
{
Iterator it = Begin();//得到第一个结点的地址
while (it != End())
{
it=Erase(it);
}
_head->_next = _head;
_head->_pre = _head;
}
template<class Iterator, class T>
Iterator Find(Iterator first, Iterator last, const T& data)
{
while (first != last)
{
if (*first == data)
return first;
++first;
}
}
};
下面是我的测试代码和结果,你可以根据自己的想法去测试
void TestList()
{
int arr[] = { 1, 2, 3, 4, 5 };
ListHead<int> s(arr, sizeof(arr) / sizeof(*arr));
s.PushBack(6);
s.PushFront(0);
ListHead<int>::Iterator it = s.Begin();
while (it != s.End())
{
cout << *it << "->";
++it;
}
cout << *it;
cout << "->NULL" << endl;
cout << "Size()="<<s.Size() << endl;
ListHead<int>::Iterator s1 = s.Find(s.Begin(), s.End(), 2);
cout <<"s1=" <<*s1 << endl;
ListHead<int>::Iterator s2 = s.Insert(s.Begin(), 100);
ListHead<int>::Iterator it1 = s.Begin();
while (it1 != s.End())
{
cout << *it1 << "->";
++it1;
}
cout << *it1;
cout << "->NULL" << endl;
}
下面给出整个项目的完整代码,
template<class T>
struct ListNode//定义结点的类
{
public:
ListNode<T> *_pre;//后指针
ListNode<T> *_next;//前指针
T _data;//储存数据
public:
ListNode(const T& data = T())//构造函数
:_pre(0)
, _next(0)
, _data(data){}
};
template<class T,class Ref,class Src>//迭代器的类
class Iterator
{
public:
ListNode<T>* _pCur;
public:
Iterator()//构造函数
: _pCur(0){}
Iterator(ListNode<T>* pCur)//有参数的构造函数
:_pCur(pCur){}
Iterator(const Iterator<T,Ref,Src>& s)//拷贝构造函数
:_pCur(s._pCur){}
Ref& operator*()
{
return _pCur->_data;
}
Src* operator->()
{
return &(_pCur->_data);
}
Iterator < T, Ref, Src > operator++(int)//后置++
{
Iterator<T, Ref, Src> temp(*this);
_pCur = _pCur->_next;
return temp;
}
Iterator < T, Ref, Src > operator++()//前置++
{
_pCur = _pCur->_next;
return *this;
}
Iterator < T, Ref, Src > operator--()//前置--
{
_pCur = _pCur->_pre;
return *this;
}
Iterator < T, Ref, Src > operator--(int)//后置--
{
Iterator < T, Ref, Src > temp(*this)
_pCur = _pCur->_pre;
return temp;
}
bool operator!=(const Iterator < T, Ref, Src >& s)
{
return _pCur != s._pCur;
}
bool operator==(const Iterator < T, Ref, Src >& s)
{
return _pCur == s->_pPcur;
}
};
//可以直接在里面使用迭代器
template<class T>
class ListHead//封装头指针的类
{
public:
ListNode<T> *_head;//定义头指针成员变量,指向结点的指针
typedef Iterator<T, T&, T*> Iterator;//在这个类中定义迭代器
public:
ListHead()//无参构造函数
:_head(new ListNode<T>)//给头结点开辟空间
{
_head->_pre = _head;
_head->_next = _head;
}
ListHead(const T*array, size_t size)//有参数的构造函数
:_head(new ListNode<T>)//开辟头结点
{
_head->_next = _head;
_head->_pre = _head;
for (size_t i =0 ; i < size; i++)
{
PushBack(array[i]);
}
}
/*List(const List& l);
List& operator=(const List& l);*/
~ListHead()
{
Clear();
delete []_head;
_head = NULL;
}
void PushBack(const T& data)
{
ListNode<T> *NewNode = new ListNode<T>(data);
if (Empty())
{
_head->_next = NewNode;
NewNode->_next = _head;
NewNode->_pre = _head;
_head->_pre = NewNode;
}
else
{
ListNode<T>* pLast = _head->_pre;//找到最后一个结点
NewNode->_next = _head;
NewNode->_pre = pLast;
pLast->_next = NewNode;
_head->_pre = NewNode;
}
}
void PushFront(const T& data)
{
ListNode<T> *NewNode = new ListNode<T>(data);
if (Empty())
{
_head->_next = NewNode;//头指针指向第一个结点
NewNode->_next = _head;//第一个结点next指向头指针
NewNode->_pre = _head;//第一个结点pre向头指针
_head->_pre = NewNode;//头指针pre指向第一个结点
}
else
{
NewNode->_next = _head->_next;
NewNode->_pre = _head;
_head->_next->_pre = NewNode;
_head->_next = NewNode;
}
}
void PopFront()//头删除
{
if (!Empty())
{
ListNode<T> *p = _head->_next;//保存第一个结点
_head->_next = p->_next;
p->_next->_pre = _head;
delet p;
}
}
void PopBack()//尾删除
{
if (!Empty())
{
ListNode<T> *p = _head->_pre->_pre;//保存倒数第二个结点
delete p->_next;//销毁最后一个结点
p->_next = _head;
_head->_pre = p;
}
}
Iterator Begin()//返回第一个结点的地址
{
return Iterator(_head->_next);
}
Iterator End()//返回最后一个结点的地址
{
return Iterator(_head->_pre);
}
Iterator Insert(Iterator pos, const T& data)//指定位置插入,返回插入的结点
{
ListNode<T>* pNewNode = new ListNode<T>(data);
pNewNode->_next = pos._pCur;
pos._pCur->_pre->_next = pNewNode;
pNewNode->_pre = pos._pCur->_pre;
pos._pCur->_pre = pNewNode;
return Iterator(pNewNode);
}
Iterator Erase(Iterator pos)//指定位置删除,返回删除的下一个结点
{
ListNode<T> *src = pos._pCur->_next;
pos._pCur->_pre->_next = pos._pCur->_next;
pos._pCur->_next->_pre = pos._pCur->_pre;
delete pos._pCur;
pos._pCur = NULL;
return src;
}
bool Empty()const
{
return _head->_pre == _head;//只有一个头结点
}
size_t Size()const
{
ListNode<T> *dest = _head->_next;//标记第一个结点
size_t count = 0;
while (dest!= _head)
{
dest = dest->_next;
count++;
}
return count;
}
T& Front()
{
return _head->_next->data;
}
const T& Front()const
{
return _head->_next->data;
}
T& Back()
{
return _head->_pre->data;
}
const T& Back()const
{
return _head->_pre->data;
}
void Clear()
{
Iterator it = Begin();//得到第一个结点的地址
while (it != End())
{
it=Erase(it);
}
_head->_next = _head;
_head->_pre = _head;
}
template<class Iterator, class T>
Iterator Find(Iterator first, Iterator last, const T& data)
{
while (first != last)
{
if (*first == data)
return first;
++first;
}
}
};
void TestList()
{
int arr[] = { 1, 2, 3, 4, 5 };
ListHead<int> s(arr, sizeof(arr) / sizeof(*arr));
s.PushBack(6);
s.PushFront(0);
ListHead<int>::Iterator it = s.Begin();
while (it != s.End())
{
cout << *it << "->";
++it;
}
cout << *it;
cout << "->NULL" << endl;
cout << "Size()="<<s.Size() << endl;
ListHead<int>::Iterator s1 = s.Find(s.Begin(), s.End(), 2);
cout <<"s1=" <<*s1 << endl;
ListHead<int>::Iterator s2 = s.Insert(s.Begin(), 100);
ListHead<int>::Iterator it1 = s.Begin();
while (it1 != s.End())
{
cout << *it1 << "->";
++it1;
}
cout << *it1;
cout << "->NULL" << endl;
}
只需要加上头文件和主函数就可以正常运行测试了。