vs2017里面在运用模板时不允许将定义与实现分开来放 即.h文件内容要和.cpp文件内容放在一起
首先是节点类的模板定义即部分函数功能
#pragma once
template<class T>
class ListNode
{
private:
T date; //定义节点类型 一共两个数据 一个是存放数据值 一个用来指向下一个节点
ListNode<T>* link;
public:
ListNode() :link(NULL) {} //初始化
ListNode(T value) :date(value), link(NULL) {} //带参数的初始化
~ListNode() {} //析构函数
void SetLink(ListNode<T> * next); //设置节点的next指针的指向
void SetDate(T value); //设置该节点的数据值
ListNode<T> * GetLink(); //获得节点的next指针
T& GetDate(); //获得节点的数据值
};
template<class T>
void ListNode<T>::SetLink(ListNode<T> * next)
{
link = next;
}
template<class T>
void ListNode<T>::SetDate(T value)
{
date = value;
}
template<class T>
ListNode<T>* ListNode<T>::GetLink()
{
return link;
}
template<class T>
T& ListNode<T>::GetDate()
{
return date;
}
节点类定义好之后,就是定义链表类
#pragma once
#include"ListNode.h"
template<class T>
class List
{
private:
ListNode<T> *head; //初始链表只有头和尾两个节点
ListNode<T> *tail;
public:
List();
~List();
bool AddTail(T value); //在节尾插入一个节点
bool InsertAt(int index, T value); //在指定位置插入一个节点
bool RemoveTail(); //删除节尾的节点
bool RemoveAt(int index); //删除指定位置的节点
T& GetAt(int index); //获得指定位置节点的值 返回一个对应类型的引用
bool IsEmpty(); //判断链表是否为空 为空返回true
int GetCount(); //获得链表的节点数
void RemoveAll(); //删除所有节点
ListNode<T>* GetHead(); //获得头节点
ListNode<T>* GetTail(); //获得尾节点
ListNode<T>* GetNodeAt(int index); //获得索引对应的节点
ListNode<T>* GetCur(); //获得当前指针的位置
ListNode<T>* ToWardCur(); //指针向后移动一位
};
template<class T>
List<T>::List() //初始化List类 创建表头表尾
{
head = new ListNode<T>();
tail = head;
tail->SetLink(NULL);
}
template<class T>
List<T>::~List()
{
RemoveAll();
delete head;
}
template<class T>
bool List<T>::AddTail(T value)
{
ListNode<T> *add = new ListNode<T>(value); //新建节点 用value值初始化
tail->SetLink(add); //tail的link指针指向新节点
tail = tail->GetLink(); //tail指针指向新的表尾
tail->SetLink(NULL); //将表尾设置成空
if (tail != NULL)
return true;
else
return false;
}
template<class T>
bool List<T>::InsertAt(int index,T value)
{
//判断索引是否正确
if (index > this->GetCount() - 1 || index < 0)
{
cout << "A wrong position!\n";
return false;
}
ListNode<T> * current = head; //从头开始寻找index位置
while (index)
{
current = current->GetLink();
index--;
}
ListNode<T> * add = new ListNode<T>(value);
add->SetLink(current->GetLink());
current->SetLink(add);
if (current->GetLink() != NULL)
return true;
else
return false;
}
template<class T>
bool List<T>::RemoveTail()
{ //利用RemoveAt(int index)实现
return RemoveAt(this->GetCount() - 1);
}
template<class T>
bool List<T>::RemoveAt(int index)
{//判断索引是否正确
if (index > this->GetCount() - 1 || index < 0)
{
cout << "A wrong position!\n";
return false;
}
ListNode<T> * cur, *curPre; //利用两个指针
cur = head;
curPre = cur->GetLink();
while (index)
{
cur = cur->GetLink();
curPre = curPre->GetLink();
index--;
}
if (tail == curPre)
cur = tail;
cur->SetLink(curPre->GetLink());
delete curPre;
if (curPre != NULL)
return true;
else
return false;
}
template<class T>
T& List<T>::GetAt(int index)
{
//判断索引是否正确
if (index > this->GetCount() - 1 || index < 0)
{
cout << "A wrong position!\n";
}
ListNode<T>* cur = head;
while (index)
{
cur = cur->GetLink();
index--;
}
return cur->GetDate();
}
template<class T>
bool List<T>::IsEmpty()
{
if (this->GetHead() == this->GetTail())
return true;
return false;
}
template<class T>
int List<T>::GetCount()
{
int cnt = 0;
ListNode<T> * cur = head;
cnt++;
while (cur != this->GetTail())
{
cur = cur->GetLink();
cnt++;
}
return ++cnt;
}
template<class T>
void List<T>::RemoveAll()
{
ListNode<T> *cur;
while (head->GetLink() != NULL)
{
cur = head->GetLink();
head->SetLink(cur->GetLink());
delete cur;
}
tail = head;
}
template<class T>
ListNode<T>* List<T>::GetHead()
{
return head;
}
template<class T>
ListNode<T>* List<T>::GetTail()
{
return tail;
}
template<class T>
ListNode<T>* List<T>::GetNodeAt(int index)
{
//判断索引是否正确
if (index > this->GetCount() - 1 || index < 0)
{
cout << "A wrong position!\n";
return NULL;
}
ListNode<T> * cur = head;
while (index) {
cur = cur->GetLink();
index--;
}
return cur;
}
有些没加注释 有空再加吧