#pragma once
//2021/06/29 wangdong 链表结点的定义
template<typename T>
struct LinkNode
{
T data;
LinkNode* pNext;
LinkNode(const T& _data)
{
data = _data;
pNext = nullptr;
}
};
/*
* @projectName: CTools
* @brief:
* @author: wangdong
* @date: 2021/06/29
* @introduce: 单链表的基本操作
*/
template<typename T>
class CLink
{
public:
CLink();
~CLink();
public:
/**************************************
* @authorTime : wangdong 2021/06/29
* @version : V1.0
* @input : 数据
* @output : void
* @return : void
* @functionDesc : TOP0:从头部插入数据
**************************************/
void InsertDataFromHead(const T& data);
/**************************************
* @authorTime : wangdong 2021/06/29
* @version : V1.0
* @input : void
* @output : void
* @return : void
* @functionDesc : TOP0: 从尾部插入链表数据
**************************************/
void InsertDataFromTail(const T& data);
/**************************************
* @authorTime : wangdong 2021/06/29
* @version : V1.0
* @input : void
* @output : void
* @return : void
* @functionDesc : TOP0: 给指定数据后面插入数据
**************************************/
void InsertDataAfterPreData(const T& PreData, const T& nextData);
/**************************************
* @authorTime : wangdong 2021/06/29
* @version : V1.0
* @input : void
* @output : void
* @return : void
* @functionDesc : TOP0: 删除指定数据
**************************************/
void DeleteData(const T& data);
/**************************************
* @authorTime : wangdong 2021/06/29
* @version : V1.0
* @input : void
* @output : void
* @return : void
* @functionDesc : TOP0:更新指定数据
**************************************/
void UpdateDataFomPos(const T& OldData, const T& newData);
/**************************************
* @authorTime : wangdong 2021/06/29
* @version : V1.0
* @input : void
* @output : void
* @return : void
* @functionDesc : TOP0: 反转链表
**************************************/
void ReverseLink();
/**************************************
* @authorTime : wangdong 2021/06/29
* @version : V1.0
* @input : void
* @output : void
* @return : void
* @functionDesc : TOP0: 打印链表数据
**************************************/
void Print();
private:
/**************************************
* @authorTime : wangdong 2021/06/29
* @version : V1.0
* @input : void
* @output : void
* @return : void
* @functionDesc : TOP0: 用来查找数据的上一个节点
**************************************/
LinkNode<T>* FindPreviousNode(const T& data);
private:
LinkNode<T>* m_pHeadNode = nullptr;
};
/*********************函数的实现************************/
/*
* @authorTime : wangdong 2021/06/29
* @version : V1.0
* @desc :用来查找上个节点
* @modifyDesc :
*/
template<typename T>
LinkNode<T>* CLink<T>::FindPreviousNode(const T& data)
{
LinkNode<T>* pNode = m_pHeadNode;
for (;nullptr != pNode->pNext; pNode = pNode->pNext)
{
if (data == pNode->pNext->data)
{
return pNode;
}
}
return nullptr;
}
/*
* @authorTime : wangdong 2021/06/29
* @version : V1.0
* @desc :打印链表的数据
* @modifyDesc :
*/
template<typename T>
void CLink<T>::Print()
{
LinkNode<T>* pNode = m_pHeadNode;
while (nullptr != pNode->pNext)
{
pNode = pNode->pNext;
cout << pNode->data<<" ";
}
cout << endl;
}
/*
* @authorTime : wangdong 2021/06/30
* @version : V1.0
* @desc :更新数据
* @modifyDesc :
*/
template<typename T>
void CLink<T>::UpdateDataFomPos(const T& OldData, const T& newData)
{
LinkNode<T>* pNode = FindPreviousNode(OldData);
if (nullptr == pNode)
{
return;
}
pNode->pNext->data = newData;
}
/*
* @authorTime : wangdong 2021/06/30
* @version : V1.0
* @desc :链表的反转
* @modifyDesc :
*/
template<typename T>
void CLink<T>::ReverseLink()
{
LinkNode<T>* pNextNode = nullptr;
LinkNode<T>* pNode = m_pHeadNode->pNext;
m_pHeadNode->pNext = nullptr; //先将原来的链表头节点清空
//TOP0: 判断节点是否为空
while (nullptr != pNode)
{
//TOP1: 先存下来当前节点的后续节点
pNextNode = pNode->pNext;
//TOP2: 利用头插法将数据放进行
pNode->pNext = m_pHeadNode->pNext;
m_pHeadNode->pNext = pNode;
//将当前节点赋值给后续节点
pNode = pNextNode;
}
}
/*
* @authorTime : wangdong 2021/06/30
* @version : V1.0
* @desc :删除指定的数据
* @modifyDesc :
*/
template<typename T>
void CLink<T>::DeleteData(const T& data)
{
LinkNode<T>* pNode = FindPreviousNode(data);
if (nullptr == pNode)
{
return;
}
//TOP: 先删除数据的内存
LinkNode<T>* pTemp = pNode->pNext;
pNode->pNext = pNode->pNext->pNext;
delete pTemp;
pTemp = nullptr;
}
/*
* @authorTime : wangdong 2021/06/30
* @version : V1.0
* @desc 在一个已有的数据前面插入一个数据
* @modifyDesc :
*/
template<typename T>
void CLink<T>::InsertDataAfterPreData(const T& PreData, const T& nextData)
{
LinkNode<T>* pNode = FindPreviousNode(PreData);
if (nullptr == pNode)
{
return;
}
LinkNode<T>* pNewNode = new LinkNode<T>(nextData);
pNewNode->pNext = pNode->pNext;
pNode->pNext = pNewNode;
}
/*
* @authorTime : wangdong 2021/06/29
* @version : V1.0
* @desc :从尾部插入数据
* @modifyDesc :
*/
template<typename T>
void CLink<T>::InsertDataFromTail(const T& data)
{
LinkNode<T>* pHead = m_pHeadNode;
//TOP0: 先找到最后一个节点
while (nullptr != pHead->pNext)
{
pHead = pHead->pNext;
}
//TOP1:创建一个结点,将数据赋值给这个结点
LinkNode<T>* pNode = new LinkNode<T>(data);
//TOP2: 将最后一个结点指向新创建的节点
pHead->pNext = pNode;
}
/*
* @authorTime : wangdong 2021/06/29
* @version : V1.0
* @desc :从头部插入数据
* @modifyDesc :
*/
template<typename T>
void CLink<T>::InsertDataFromHead(const T& data)
{
if (nullptr == m_pHeadNode)
{
return;
}
//TOP0 先创建一个节点,将数据赋值
LinkNode<T>* pNode = new LinkNode<T>(data);
//TOP1 将新节点指向原先头节点指向的数据
pNode->pNext = m_pHeadNode->pNext;
//TOP2 头节点指向新节点
m_pHeadNode->pNext = pNode;
}
/*
* @authorTime : wangdong 2021/06/30
* @version : V1.0
* @desc :析构函数,删除内存
* @modifyDesc :
*/
template<typename T>
CLink<T>::~CLink()
{
LinkNode<T>* pNode = m_pHeadNode;
while (nullptr != pNode)
{
LinkNode<T>* pTempNode = pNode;
pNode = pNode->pNext;
cout << "删除了数据" << pTempNode->data<<endl;
delete pTempNode;
pTempNode = nullptr;
}
}
/*
* @authorTime : wangdong 2021/06/29
* @version : V1.0
* @desc :创建头节点
* @modifyDesc :
*/
template<typename T>
CLink<T>::CLink()
{
//2021/06/29 wangdong 初始化头节点
if (nullptr == m_pHeadNode)
{
m_pHeadNode = new LinkNode<T>(-1);
}
}
测试代码如下:
#include "CLink.h"
int main()
{
CLink<int> clsLink;
clsLink.InsertDataFromHead(20);
clsLink.InsertDataFromHead(30);
clsLink.InsertDataFromHead(40);
clsLink.InsertDataFromHead(50);
clsLink.Print();
clsLink.InsertDataAfterPreData(50, 100);
clsLink.InsertDataFromTail(60);
clsLink.InsertDataFromTail(70);
clsLink.InsertDataFromTail(80);
clsLink.InsertDataFromTail(90);
clsLink.Print();
clsLink.ReverseLink();
clsLink.Print();
clsLink.DeleteData(90);
clsLink.Print();
return 0;
}
运行结果如下:
50 40 30 20
100 50 40 30 20 60 70 80 90
90 80 70 60 20 30 40 50 100
80 70 60 20 30 40 50 100
删除了数据-1
删除了数据80
删除了数据70
删除了数据60
删除了数据20
删除了数据30
删除了数据40
删除了数据50
删除了数据100