#ifndef YITERATOR_H_
#define YITERATOR_H_
template<class T>
//在外部自定义一个迭代器类
class yiterator
{
public:
virtual void outputd(){ };
};
#endif /* YITERATOR_H_ */
#ifndef DCIRCULARLISTHEADER_H_
#define DCIRCULARLISTHEADER_H_
#include"yiterator.h"
#include "linearList.h"
template <typename T>
struct chainNoded
{
T element;
chainNoded<T> *next;//指向下一个节点
chainNoded<T>* pre;//指向前一个节点
chainNoded() {next =NULL;
pre = NULL;}
chainNoded(const T& element){
this->element = element;
next =NULL;
pre = NULL;
}
chainNoded(const T& element, chainNoded* next,chainNoded* pre)
{
this->element = element;
this->next = next;
this->pre = pre;
}
};
template<class T>
class dcircularlistheader:public linearList<T>
{
public:
dcircularlistheader(int initialCapacity = 10);
~dcircularlistheader();
bool empty() const {return listSize == 0;}//判断是否为空
int size() const {return listSize;}//返回链表节点数
T& get(int theIndex) const;// 按照索引返回元素值
int indexOf(const T& theElement) const;//根据元素返回索引值
void erase(int theIndex);//删除函数
void insert(int theIndex, const T& theElement);//插入
void output(std::ostream& out) const;//按序输出
chainNoded<T>* first(){ return headerNode;}//返回头结点的值
class iterator;
// 返回迭代器
iterator* iteratord(chainNoded<T>* a){
return new iterator(a);
}
protected:
void checkIndex(int theIndex) const;
chainNoded<T>* headerNode;
int listSize;
public:
class iterator:public yiterator<T>
{
public:
iterator(chainNoded<T>* theNode=NULL)
{ node=theNode;
}
T& operator*() const {return node->element;}//取值
T* operator->() const{return &node->element;}
iterator& operator++()
{
node=node->next;
return *this;
}
iterator operator++(int)
{iterator old = *this;
node = node->next;
return old;
}
iterator& operator--()
{
node=node->pre;
return *this;
}
iterator operator--(int)
{iterator old = *this;
node = node->pre;
return old;
}
bool operator!=(const iterator right)const
{
return node !=right.node;
}
bool operator==(const iterator right)const
{
return node==right.node;
}
iterator begin() const {return iterator(node->next);}//输出当前节点
iterator end() const{return iterator(node->pre); }//输出当前节点的前一个节点
//使用迭代器进行输出链表
virtual void outputd(){
for(iterator iter=begin();iter!=++end();++iter)
std::cout<<*iter<<" ";
std::cout<<std::endl; }
private:
chainNoded<T>* node;
};
};
#endif /* DCIRCULARLISTHEADER_H_ */ * Created on: 2018年7月12日
#include "dcircularlistheader.h"
template<class T>
dcircularlistheader<T>::dcircularlistheader(int initialCapacity)
{if (initialCapacity < 1)
throw std::invalid_argument("Initial capacity = " + std::to_string(initialCapacity) + " Must be > 0");
headerNode = new chainNoded<T>();
//令头结点起初指向他自己
headerNode->pre = headerNode;
headerNode->next = headerNode;
listSize = 0;
}
template<class T>
dcircularlistheader<T>::~dcircularlistheader(){
chainNoded<T>*q=headerNode;
while (q->next!=headerNode )
{// delete firstNode
chainNoded<T>* nextNode = q->next;//保存下一个节点
delete q;//释放节点指向的空间
q = nextNode;
}
delete headerNode;//最后删除头结点指向的空间
}
template<class T>
void dcircularlistheader<T>::checkIndex(int theIndex) const
{//检查索引值是否合法
{if(theIndex < 0 || theIndex >=listSize){
throw std::out_of_range("index = " + std::to_string(theIndex) + " size = " + std::to_string(listSize)); //C++11标准引入的
}
}
}
template<class T>
T& dcircularlistheader<T>::get(int theIndex) const
{
checkIndex(theIndex);
chainNoded<T>* currentNode = headerNode->next;//先令当前节点指向第一个节点
for(int i = 0;i<theIndex;i++)//移动索引值次
currentNode = currentNode->next;//移动指针
return currentNode->element;//返回目标元素
}
template<class T>
int dcircularlistheader<T>::indexOf(const T& theElement) const
{
chainNoded<T>* currentNode = headerNode->next;
int index = 0;
//根据条件移动指针
while (currentNode->element != theElement&¤tNode!=headerNode)
{
currentNode = currentNode->next;
index++;
}
//若最终移动到头结点则没找到
if (currentNode == headerNode)
return -1;
else
return index;
}
template<class T>
void dcircularlistheader<T>::erase(int theIndex)
{
checkIndex(theIndex);
chainNoded<T>*deleteNode;
chainNoded<T>* p = headerNode;
for(int i = 0;i < theIndex;i++)//将指针移动到到目标节点的前一个节点
p = p->next;
deleteNode = p->next;//保存目标节点
p->next->next->pre=p;//令目标节点的前驱等于目标节点的前驱
p->next = p->next->next;//目标节点的后继等于目标节点的后继
listSize--;// 链表大小减一
delete deleteNode;
}
template<class T>
void dcircularlistheader<T>::insert(int theIndex, const T& theElement)
{
//判断是否合法
if (theIndex != listSize)
checkIndex(theIndex);
//移动指针到待插入索引的前一个位置
chainNoded<T>* p = headerNode;
for (int i = 0; i < theIndex; i++)
p = p->next;
p->next = new chainNoded<T>(theElement, p->next,p);//插入新节点
p->next->next->pre=p->next;//原位置节点指向新插入节点
listSize++;//链表大小加一
}
template<class T>
void dcircularlistheader<T>::output(std::ostream& out) const
{
chainNoded<T> *p = headerNode->next;//指向第一个节点
out <<std::endl;
//一直循环输出每一个元素
while(p != headerNode){
out << p->element <<" ";
p = p->next;
}
out << std::endl;
// for (chainNode<T>* currentNode = headerNode->next;
// currentNode != headerNode;
// currentNode = currentNode->next)
// out << currentNode->element << " ";
}
//对<<运算符进行重载
template <class T>
std::ostream& operator<<(std::ostream& out, const dcircularlistheader<T>& x)
{x.output(out); return out;}
测试用例
1、对每个函数的测试数据
2、对程序整体的测试数据
#include <numeric>//accumulate
#include <algorithm>
#include"dcircularlistheader.cpp"
using std::cout;
using std::endl;
int main()
{
// test constructor
dcircularlistheader<int> y, z;
// test size
cout << "Initial size of y and z = "
<< y.size() << ", "
<< z.size() << endl;
// test insert
y.insert(0, 2);
y.insert(1, 6);
y.insert(0, 1);
y.insert(2, 4);
y.insert(3, 5);
y.insert(2, 3);
cout << "Inserted 6 integers, list y should be 1 2 3 4 5 6" << endl;
cout << "Size of y = " << y.size() << endl;
//测试删除函数
y.erase(5);
//测试输出函数
y.output(cout);
cout << endl << "Testing overloaded <<" << endl;
cout << y << endl;
// test indexOf
int index = y.indexOf(4);
if (index < 0) cout << "4 not found" << endl;
else cout << "The index of 4 is " << index << endl;
index = y.indexOf(7);
if (index < 0) cout << "7 not foundd" << endl;
else cout << "The index of 7 is " << index << endl;
//测试迭代器
yiterator<int> *gi= y.iteratord(y.first());
gi->outputd();
cout<<"aaaa";
return 0;
}
- 测试结果
Initial size of y and z = 0, 0
Inserted 6 integers, list y should be 1 2 3 4 5 6
Size of y = 6
1 2 3 4 5
Testing overloaded <<
1 2 3 4 5
Aaaa
The index of 4 is 37 not foundd1 2 3 4 5