1、单向链表
下面代码定义了一个单向链表,又循环添加元素,并进行了遍历。这段代码的问题在于只能接受CNode类型。
#include "stdafx.h"
#include "iostream.h"
class CNode //定义一个节点类
{
public:
CNode *m_pNext; //定义一个节点指针,指向下一个节点
int m_nData; //定义节点的数据
CNode() //定义节点类的构造函数
{
m_pNext = NULL; //将m_pNext设置为空
}
};
class CList //定义链表类CList类
{
private:
CNode *m_pHeader; //定义头节点
int m_nNodeSum; //节点数量
public:
CList() //定义链表的构造函数
{
m_pHeader = NULL; //初始化m_pHeader
m_nNodeSum = 0; //初始化m_NodeSum
}
CNode* MoveTrail() //移动到尾节点
{
CNode* pTmp = m_pHeader; //定义一个临时节点,将其指向头节点
for (int i=1;i<m_nNodeSum;i++) //遍历节点
{
pTmp = pTmp->m_pNext; //获取下一个节点
}
return pTmp; //返回尾节点
}
void AddNode(CNode *pNode) //添加节点
{
if (m_nNodeSum == 0) //判断链表是否为空
{
m_pHeader = pNode; //将节点添加到头节点中
}
else //链表不为空
{
CNode* pTrail = MoveTrail(); //搜索尾节点
pTrail->m_pNext = pNode; //在尾节点处添加节点
}
m_nNodeSum++; //使链表节点数量加1
}
void IterateList () //遍历链表
{
if (m_nNodeSum > 0) //判断链表是否为空
{
CNode* pTmp = m_pHeader; //定义一个临时节点,将其指向头节点
cout << pTmp->m_nData << endl; //输出节点数据
for (int i=1; i<m_nNodeSum; i++) //遍历其他节点
{
pTmp = pTmp->m_pNext; //获取下一个节点
cout <<pTmp->m_nData << endl; //输出节点数据
}
}
}
~CList() //定义链表析构函数
{
if (m_nNodeSum > 0) //链表不为空
{
CNode *pDelete = m_pHeader; //定义一个临时节点,指向头节点
CNode *pTmp = NULL; //定义一个临时节点
for(int i=0; i<m_nNodeSum; i++) //遍历节点
{
pTmp = pDelete->m_pNext; //获取下一个节点
delete pDelete; //释放当前节点
pDelete = pTmp; //将下一个节点设置为当前节点
}
m_nNodeSum = 0; //将m_NodeSum设置为0
pDelete = NULL; //将pDelete置为空
pTmp = NULL; //将pTmp置为空
}
m_pHeader = NULL; //将m_pHeader置为空
}
};
int main(int argc, char* argv[])
{
CList list; //定义链表对象
for(int i=0; i<5; i++) //利用循环向链表中添加5个节点
{
CNode *pNode = new CNode(); //构造节点对象
pNode->m_nData = i; //设置节点数据
list.AddNode(pNode); //添加节点到链表
}
list.IterateList(); //遍历节点
return 0;
}
2、模板链表
下面的代码对原来的CList类进行了修改,将节点类CNode替换为了模板类Type,这样,链表类CList就能适应不同类型的节点。模板类由template关键字开始,后面跟着模板参数列表,由<>表示,模板参数列表不能为空,它可以是一个参数类型,即由class或typename和一个标识符构成,也可以是一个非参数类型。另外一个模板类可以有多个类型参数。
#include "stdafx.h"
#include "iostream.h"
template <class Type> //定义类模板
class CList //定义链表类CList类
{
private:
Type *m_pHeader; //定义头节点
int m_nNodeSum; //节点数量
public:
CList() //定义链表的构造函数
{
m_pHeader = NULL; //初始化m_pHeader
m_nNodeSum = 0; //初始化m_NodeSum
}
Type* MoveTrail() //移动到尾节点
{
Type* pTmp = m_pHeader; //定义一个临时节点,将其指向头节点
for (int i=1;i<m_nNodeSum;i++) //遍历节点
{
pTmp = pTmp->m_pNext; //获取下一个节点
}
return pTmp; //返回尾节点
}
void AddNode(Type *pNode) //添加节点
{
if (m_nNodeSum == 0) //判断链表是否为空
{
m_pHeader = pNode; //将节点添加到头节点中
}
else //链表不为空
{
Type* pTrail = MoveTrail(); //搜索尾节点
pTrail->m_pNext = pNode; //在尾节点处添加节点
}
m_nNodeSum++; //使链表节点数量加1
}
void IterateList() //遍历链表
{
if (m_nNodeSum > 0) //判断链表是否为空
{
Type* pTmp = m_pHeader; //定义一个临时节点,将其指向头节点
cout << pTmp->m_nData << endl; //输出节点数据
for (int i=1; i<m_nNodeSum; i++) //遍历其他节点
{
pTmp = pTmp->m_pNext; //获取下一个节点
cout <<pTmp->m_nData << endl; //输出节点数据
}
}
}
~CList() //定义链表析构函数
{
if (m_nNodeSum > 0) //链表不为空
{
Type *pDelete = m_pHeader; //定义一个临时节点,指向头节点
Type *pTmp = NULL; //定义一个临时节点
for(int i=0; i<m_nNodeSum; i++) //遍历节点
{
pTmp = pDelete->m_pNext; //获取下一个节点
delete pDelete; //释放当前节点
pDelete = pTmp; //将下一个节点设置为当前节点
}
m_nNodeSum = 0; //将m_NodeSum设置为0
pDelete = NULL; //将pDelete置为空
pTmp = NULL; //将pTmp置为空
}
m_pHeader = NULL; //将m_pHeader置为空
}
};
class CNet //定义一个节点类
{
public:
CNet *m_pNext; //定义一个节点指针,指向下一个节点
int m_nData; //定义节点的数据
CNet() //定义节点类的构造函数
{
m_pNext = NULL; //将m_pNext设置为空
}
};
class CNode //定义一个节点类
{
public:
CNode *m_pNext; //定义一个节点指针,指向下一个节点
int m_nData; //定义节点的数据
CNode() //定义节点类的构造函数
{
m_pNext = NULL; //将m_pNext设置为空
}
};
int main(int argc, char* argv[])
{
CList<CNode> nodeList; //定义链表对象
for(int i=0; i<5; i++) //利用循环向链表中添加5个节点
{
CNode *pNode = new CNode(); //构造节点对象
pNode->m_nData = i; //设置节点数据
nodeList.AddNode(pNode); //添加节点到链表
}
nodeList.IterateList(); //遍历节点
CList<CNet> netList; //定义链表对象
for(int j=0; j<5; j++) //利用循环向链表中添加5个节点
{
CNet *pNode = new CNet(); //构造节点对象
pNode->m_nData = j; //设置节点数据
netList.AddNode(pNode); //添加节点到链表
}
netList.IterateList(); //遍历节点
return 0;
}
3、模板类的静态数据成员
运行代码后可知,nodeList和netList均有各自的静态数据成员。但是,对于同一类型的模板实例,其静态数据成员是共享的。
#include "stdafx.h"
#include "iostream.h"
template <class Type> //定义一个模板类
class CList //定义CList类
{
private:
Type *m_pHeader; //定义头节点
int m_nNodeSum; //节点数量
public:
static int m_ListValue; //定义静态数据成员
CList() //定义构造函数
{
m_pHeader = NULL; //将m_pHeader置为空
m_nNodeSum = 0; //将m_nNodeSum置为0
}
};
template <class Type>
int CList<Type>::m_ListValue = 100; //初始化静态数据成员
class CNet //定义一个节点类
{
public:
CNet *m_pNext; //定义一个节点指针,指向下一个节点
int m_nData; //定义节点的数据
CNet() //定义节点类的构造函数
{
m_pNext = NULL; //将m_pNext设置为空
}
};
class CNode //定义一个节点类
{
public:
CNode *m_pNext; //定义一个节点指针,指向下一个节点
int m_nData; //定义节点的数据
CNode() //定义节点类的构造函数
{
m_pNext = NULL; //将m_pNext设置为空
}
};
int main(int argc, char* argv[])
{
CList<CNode> nodeList; //实例化类模板
nodeList.m_ListValue = 200; //设置静态数据成员
CList<CNet> netList; //实例化类模板
netList.m_ListValue = 300; //设置静态数据成员
cout << "nodeList实例:" << nodeList.m_ListValue << endl; //输出静态数据成员
cout << "netList实例: " << netList.m_ListValue << endl; //输出静态数据成员
return 0;
}
4、同一类型的模板实例共享静态数据成员
下面代码中的nodeList和netList均为CNode模板类的实例,运行可知,它们确实共享了静态数据成员。
#include "stdafx.h"
#include "iostream.h"
template <class Type> //定义一个模板类
class CList //定义CList类
{
private:
Type *m_pHeader; //定义头节点
int m_nNodeSum; //节点数量
public:
static int m_ListValue; //定义静态数据成员
CList() //定义构造函数
{
m_pHeader = NULL; //将m_pHeader置为空
m_nNodeSum = 0; //将m_nNodeSum置为0
}
};
template <class Type>
int CList<Type>::m_ListValue = 100; //初始化静态数据成员
class CNet //定义一个节点类
{
public:
CNet *m_pNext; //定义一个节点指针,指向下一个节点
int m_nData; //定义节点的数据
CNet() //定义节点类的构造函数
{
m_pNext = NULL; //将m_pNext设置为空
}
};
class CNode //定义一个节点类
{
public:
CNode *m_pNext; //定义一个节点指针,指向下一个节点
int m_nData; //定义节点的数据
CNode() //定义节点类的构造函数
{
m_pNext = NULL; //将m_pNext设置为空
}
};
int main(int argc, char* argv[])
{
CList<CNode> nodeList; //实例化类模板
nodeList.m_ListValue = 200; //设置静态数据成员
CList<CNode> netList; //实例化类模板
netList.m_ListValue = 300; //设置静态数据成员
cout << "nodeList实例:" << nodeList.m_ListValue << endl; //输出静态数据成员
cout << "netList实例: " << netList.m_ListValue << endl; //输出静态数据成员
return 0;
}