学过了模板我们就可以让链表装任意类型的数据结构。
首先链表的结构体就发生了改变
template < typename ST >struct Node {ST m_value ;Node * pNext ;//结构体构造函数Node ( const ST & v ) : m_value ( v ), pNext ( nullptr ){}//结构体析构~ Node () {}};
对迭代器进行更改
template<typename T>
class CIterator {
public:
Node<T>* m_pTemp;
public:
CIterator() : m_pTemp(nullptr) {}
CIterator(Node<T>* pNode) :m_pTemp(pNode) {}
~CIterator() {}
public:
Node<T>* operator=(Node<T>* pNode) {
m_pTemp = pNode;
return m_pTemp;
}
bool operator==(Node<T>* pNode) {
return m_pTemp == pNode;
}
bool operator!=(Node<T>* pNode) {
return m_pTemp != pNode;
}
T& operator*() {
return m_pTemp->m_value;
}
Node<T>* operator++() {
m_pTemp = m_pTemp->pNext;
return m_pTemp;
}
Node<T>* operator++(int) {
Node<T>* pTemp = m_pTemp;
m_pTemp = m_pTemp->pNext;
return pTemp; //返回的是加之前的
}
operator bool() {
return m_pTemp;
}
};
改造后的链表
template<typename T>
class CMyList {
public:
Node<T>* m_pHead; //头指针
Node<T>* m_pEnd; //头指针
int m_nLength; //链表的长度
public:
CMyList():m_pHead(nullptr), m_pEnd(nullptr), m_nLength(0){}
~CMyList() {
Node<T>* pTemp = nullptr;
while (m_pHead) {
pTemp = m_pHead; //标记
m_pHead = m_pHead->pNext; //移动
delete pTemp; //回收标记的
}
m_pHead = nullptr;
m_pEnd = nullptr;
m_nLength = 0;
}
public:
void ShowList() {
CIterator<T> ite(m_pHead); //带参数的构造,
while (ite) {
cout << *ite << " ";
ite++;
}
cout << endl;
}
void PushBack(const T& v) {
Node<T>* pNode = new Node<T>(v);
if (m_pHead) //非空链表
m_pEnd->pNext = pNode; //先连接
else //空链表
m_pHead = pNode;
m_pEnd = pNode;
++m_nLength; //长度增长
}
void PopFront() {
if (m_pHead) { //非空链表
Node<T>* pTemp = m_pHead; //标记
if (m_pHead == m_pEnd) {//1个节点
m_pHead = nullptr;
m_pEnd = nullptr;
}
else //多个节点
m_pHead = m_pHead->pNext;
delete pTemp; //回收标记的
pTemp = nullptr;
--m_nLength; //长度减少
}
}
int GetLength() { //获取链表长度
return m_nLength;
}
};
定义一个学生类
class CStudent {
public:
string m_name;
int m_age;
bool m_sex;
CStudent():m_name(""), m_age(0), m_sex(true){}
CStudent(const string & name,const int& age,const int& sex):m_name(name), m_age(age),m_sex(sex){}
~CStudent() {
m_name = "";
m_age = 0;
m_sex = true;
}
};
需要重载输出操作符,保证可以输出自定义类型
ostream& operator<<(ostream& os,const CStudent& stu) {
os << stu.m_name << " " << stu.m_age << "岁 " << (stu.m_sex == false ? "女" : "男");
return os;
}
测试
int main() {
CMyList<char> lst;
lst.PushBack('a');
lst.PushBack('b');
lst.PushBack('c');
lst.PushBack('d');
lst.ShowList();
cout << lst.GetLength() << endl;
lst.PopFront();
lst.PopFront();
lst.ShowList();
cout << lst.GetLength() << endl;
//------------------------------------------
CMyList<CStudent> lst2;
{
CStudent st1("小明", 1, 1);
lst2.PushBack(st1);
CStudent st2("小张", 2, 0);
lst2.PushBack(st2);
CStudent st3("小李", 3, 1);
lst2.PushBack(st3);
}
cout << lst2.GetLength() << endl;
lst2.ShowList();
lst2.PopFront();
cout << lst2.GetLength() << endl;
lst2.ShowList();
return 0;
}