.h
#pragma once
#include<iostream>
using namespace std;
//1. 枚举定义 返回的错误代码
enum ErrorCode
{
Error_Success, // 默认 0
Error_WrongLoc, // 默认加1,1
Error_WrongEle // 2
};
//2. 创建一个存储结点数据的结构体
typedef struct _NODE
{
int nData;
_NODE* pNext;
}NODE, *PNODE;
template <class T>
//声明
//3. 创建一个链表类来实现 单链表的增删查改
class CLinkList
{
public:
CLinkList();
public:
//3.1 在某个位置插入新结点
ErrorCode InsertEle(int _In_nLoc, T _In_nEle);
//3.2 删除链表中某个位置的结点
ErrorCode DeleteEleByLoc(int _In_nLoc);
//3.3 删除链表中含有某个元素的结点
ErrorCode DeleteEleByEle(T _In_nEle);
public:
//3.4 修改结点元素
ErrorCode ModifyEleByLoc(int _In_nLoc, T _In_nEle);
//3.5 查找结点元素
T GetEleByLoc(int _In_nLoc, T& _Out_nEle);
//3.6 清空链表(从前往后,逐个删除,最后再删除最后1个)
ErrorCode ClearList();
//3.7 获取链表长度
int GetLenth();
private:
//3.8 头节点不存数据
NODE* m_pHead;
int m_nLenth;
};
//函数的标准注释
/*
*函数名: COrderList
*函数作用:向顺序表中插入一个数据
*参数1: 插入的位置
*参数2: 插入的数据元素
*返回值: 返回错误码,哪以代表函数调用成功还是失败
*备注:
*/
.cpp
#include "CLinkList.h"
#include "CLinkList.h"
using namespace std;
//0. 初始化
template <class T>
CLinkList<T>::CLinkList()
{
m_pHead = new NODE;
m_pHead->nData = 0;
m_pHead->pNext = nullptr;
m_nLenth = 0;
}
//1.插入一个元素
//参数1:插入的位置 参数2:插入的数据元素
template <class T>
ErrorCode CLinkList<T>::InsertEle(int nLoc, T nEle)
{
//1.1 先判定插入的位置,不对就返回错误码
if (nLoc < 0 || nLoc >= m_nLenth)
{
return Error_WrongLoc;
}
// 1.2 插入的位置如果是链表尾
if (nLoc == m_nLenth)
{
//1.21 初始化pTemp 临时指针,从m_pHead开始遍历
NODE* pTemp = m_pHead;
//1.22 遍历,找到最后一个结点的指针,赋给pTemp
for (int i = 0; i < nLoc; i++)
{
pTemp = pTemp->pNext;
}
//1.23 在插入的位置创建一个临时指针,为插入的结点
NODE* pNewNode = new NODE;
//1.24 为新结点赋值
pNewNode->nData = nEle;
pNewNode->pNext = pTemp->pNext;//这个位置就是nullptr
//1.25 前一个结点的pNext指向新建结点
pTemp->pNext = pNewNode;
//1.26 长度加1
m_nLenth++;
//1.27 返回错误码信息
return Error_Success;
}
//1.3 插入的位置如果是中间
NODE* pTemp = m_pHead;
//1.31 找到插入位置的前一个节点
for (int i = 0; i < nLoc; i++)
{
pTemp = pTemp->pNext;
}
NODE* pNewNode = new NODE;
pNewNode->nData = nEle;
//1.32 将新节点的指针域指向后面的节点
pNewNode->pNext = pTemp->pNext;
//1.33 将新节点连接到前面的节点
pTemp->pNext = pNewNode;
m_nLenth++;
return Error_Success;
}
//2. 删除链表
template <class T>
ErrorCode CLinkList<T>::DeleteEleByLoc(int _In_nLoc)
{
//2.1 判断结点插入的位置,不对就返回错误码
if (_In_nLoc < 0 || _In_nLoc >= m_nLenth)
{
cout << "Location not found";
return Error_WrongLoc;
}
//2.2 遍历找到待删除节点的前一个节点
NODE* pTemp = m_pHead;
for (int i = 0; i < _In_nLoc; i++)
{
pTemp = pTemp->pNext;
}
////2.3 如果删除的是最后一个结点
//if (nLoc == m_nLenth)
//{
// pTemp->pNext = nullptr;
//}
//2.4 如果删除的是中间的结点
//2.41 先保存要删除的结点的地址
PNODE pDeleteNode = pTemp->pNext;
//2.42 将指针域链接到后一个节点
pTemp->pNext = pTemp->pNext->pNext;
//pTemp->pNext = pDeleteNode->pNext;
//2.43 删掉该指针
delete pDeleteNode;
//2.44 链表--
m_nLenth--;
//2.45 返回错误码
return Error_Success;
}
//3.删除结点
template <class T>
ErrorCode CLinkList<T>::DeleteEleByEle(T _In_nEle)
{
//3.1 定义两个指针
//pFollow 代表要删除的结点前一个结点
//pTemp 代表要删除的结点
NODE*pTemp = m_pHead;
NODE*pFollow = nullptr;
//3.2 用while循环找到需要删除结点的前一个结点
//循环条件为:当结点元素不等于输入元素,循环执行;结点元素等于输入元素时,循环停止
//pTemp此时并没有进入循环体,所以指向的仍为前一个结点
while (pTemp != nullptr&&pTemp->nData != _In_nEle)
{
//pFollow为前一个结点
pFollow = pTemp;
//使pTemp移动到下一个结点(删除结点)
pTemp = pTemp->pNext;
}
//3.3 如果没找到
if (pTemp == nullptr)
{
//3.31 打印 "Element not found"
cout << "Element not found" << endl;
//3.32 返回错误码
return Error_WrongEle;
}
//3.4 如果找到了
else
{
//3.41 将前一个结点的pNext替代删除结点的pNext
pFollow->pNext = pTemp->pNext;
//3.42 再删除当前pTemp
delete pTemp;
}
m_nLenth--;
return Error_Success;
}
//4. 修改结点
template <class T>
ErrorCode CLinkList<T>::ModifyEleByLoc(int _In_nLoc, T _In_nEle)
{
//4.1 判断边界情况
if (_In_nLoc < 0 || _In_nLoc >= m_nLenth)
{
cout << "Location not found";
return Error_WrongLoc;
}
//4.2 遍历找到
NODE*pTemp = m_pHead;
for (int i = 0; i <= _In_nLoc; i++)
{
pTemp = pTemp->pNext;
}
//4.3 修改该结点
pTemp->nData = _In_nEle;
return Error_Success;
}
//5. 查找链表,通过位置nLoc输出nEle
template <class T>
T CLinkList<T>::GetEleByLoc(int nLoc, T& _Out_nEle)
{
//判断边界条件
if (nLoc < 0 || nLoc >= m_nLenth)
{
return Error_WrongLoc;
}
//遍历通过位置查找到该结点
NODE*pTemp = m_pHead;
for (int i = 0; i <= nLoc; i++)
{
pTemp = pTemp->pNext;
}
return pTemp->nData;
}
//6. 清除链表
template <class T>
ErrorCode CLinkList<T>::ClearList()
{
NODE*pTemp = m_pHead;
for (int i = 0; i < m_nLenth; i++)
{
//6.1 从第0个结点开始,将当前的结点赋给pFollow
NODE*pFollow = pTemp;
//6.2 pTemp移动到下一个结点
pTemp = pTemp->pNext;
//6.3 删除当前结点
delete pFollow;
}
//6.4 循环完,再删除最后一个结点
delete pTemp;
m_pHead = nullptr;
m_nLenth = 0;
return Error_Success;
}
//7. 获取链表长度
template <class T>
int CLinkList<T>::GetLenth()
{
return m_nLenth;
}