.h

    1. #pragma once
    2. #include<iostream>
    3. using namespace std;
    4. //1. 枚举定义 返回的错误代码
    5. enum ErrorCode
    6. {
    7. Error_Success, // 默认 0
    8. Error_WrongLoc, // 默认加1,1
    9. Error_WrongEle // 2
    10. };
    11. //2. 创建一个存储结点数据的结构体
    12. typedef struct _NODE
    13. {
    14. int nData;
    15. _NODE* pNext;
    16. }NODE, *PNODE;
    17. template <class T>
    18. //声明
    19. //3. 创建一个链表类来实现 单链表的增删查改
    20. class CLinkList
    21. {
    22. public:
    23. CLinkList();
    24. public:
    25. //3.1 在某个位置插入新结点
    26. ErrorCode InsertEle(int _In_nLoc, T _In_nEle);
    27. //3.2 删除链表中某个位置的结点
    28. ErrorCode DeleteEleByLoc(int _In_nLoc);
    29. //3.3 删除链表中含有某个元素的结点
    30. ErrorCode DeleteEleByEle(T _In_nEle);
    31. public:
    32. //3.4 修改结点元素
    33. ErrorCode ModifyEleByLoc(int _In_nLoc, T _In_nEle);
    34. //3.5 查找结点元素
    35. T GetEleByLoc(int _In_nLoc, T& _Out_nEle);
    36. //3.6 清空链表(从前往后,逐个删除,最后再删除最后1个)
    37. ErrorCode ClearList();
    38. //3.7 获取链表长度
    39. int GetLenth();
    40. private:
    41. //3.8 头节点不存数据
    42. NODE* m_pHead;
    43. int m_nLenth;
    44. };
    45. //函数的标准注释
    46. /*
    47. *函数名: COrderList
    48. *函数作用:向顺序表中插入一个数据
    49. *参数1: 插入的位置
    50. *参数2: 插入的数据元素
    51. *返回值: 返回错误码,哪以代表函数调用成功还是失败
    52. *备注:
    53. */

    .cpp

    1. #include "CLinkList.h"
    2. #include "CLinkList.h"
    3. using namespace std;
    4. //0. 初始化
    5. template <class T>
    6. CLinkList<T>::CLinkList()
    7. {
    8. m_pHead = new NODE;
    9. m_pHead->nData = 0;
    10. m_pHead->pNext = nullptr;
    11. m_nLenth = 0;
    12. }
    13. //1.插入一个元素
    14. //参数1:插入的位置 参数2:插入的数据元素
    15. template <class T>
    16. ErrorCode CLinkList<T>::InsertEle(int nLoc, T nEle)
    17. {
    18. //1.1 先判定插入的位置,不对就返回错误码
    19. if (nLoc < 0 || nLoc >= m_nLenth)
    20. {
    21. return Error_WrongLoc;
    22. }
    23. // 1.2 插入的位置如果是链表尾
    24. if (nLoc == m_nLenth)
    25. {
    26. //1.21 初始化pTemp 临时指针,从m_pHead开始遍历
    27. NODE* pTemp = m_pHead;
    28. //1.22 遍历,找到最后一个结点的指针,赋给pTemp
    29. for (int i = 0; i < nLoc; i++)
    30. {
    31. pTemp = pTemp->pNext;
    32. }
    33. //1.23 在插入的位置创建一个临时指针,为插入的结点
    34. NODE* pNewNode = new NODE;
    35. //1.24 为新结点赋值
    36. pNewNode->nData = nEle;
    37. pNewNode->pNext = pTemp->pNext;//这个位置就是nullptr
    38. //1.25 前一个结点的pNext指向新建结点
    39. pTemp->pNext = pNewNode;
    40. //1.26 长度加1
    41. m_nLenth++;
    42. //1.27 返回错误码信息
    43. return Error_Success;
    44. }
    45. //1.3 插入的位置如果是中间
    46. NODE* pTemp = m_pHead;
    47. //1.31 找到插入位置的前一个节点
    48. for (int i = 0; i < nLoc; i++)
    49. {
    50. pTemp = pTemp->pNext;
    51. }
    52. NODE* pNewNode = new NODE;
    53. pNewNode->nData = nEle;
    54. //1.32 将新节点的指针域指向后面的节点
    55. pNewNode->pNext = pTemp->pNext;
    56. //1.33 将新节点连接到前面的节点
    57. pTemp->pNext = pNewNode;
    58. m_nLenth++;
    59. return Error_Success;
    60. }
    61. //2. 删除链表
    62. template <class T>
    63. ErrorCode CLinkList<T>::DeleteEleByLoc(int _In_nLoc)
    64. {
    65. //2.1 判断结点插入的位置,不对就返回错误码
    66. if (_In_nLoc < 0 || _In_nLoc >= m_nLenth)
    67. {
    68. cout << "Location not found";
    69. return Error_WrongLoc;
    70. }
    71. //2.2 遍历找到待删除节点的前一个节点
    72. NODE* pTemp = m_pHead;
    73. for (int i = 0; i < _In_nLoc; i++)
    74. {
    75. pTemp = pTemp->pNext;
    76. }
    77. ////2.3 如果删除的是最后一个结点
    78. //if (nLoc == m_nLenth)
    79. //{
    80. // pTemp->pNext = nullptr;
    81. //}
    82. //2.4 如果删除的是中间的结点
    83. //2.41 先保存要删除的结点的地址
    84. PNODE pDeleteNode = pTemp->pNext;
    85. //2.42 将指针域链接到后一个节点
    86. pTemp->pNext = pTemp->pNext->pNext;
    87. //pTemp->pNext = pDeleteNode->pNext;
    88. //2.43 删掉该指针
    89. delete pDeleteNode;
    90. //2.44 链表--
    91. m_nLenth--;
    92. //2.45 返回错误码
    93. return Error_Success;
    94. }
    95. //3.删除结点
    96. template <class T>
    97. ErrorCode CLinkList<T>::DeleteEleByEle(T _In_nEle)
    98. {
    99. //3.1 定义两个指针
    100. //pFollow 代表要删除的结点前一个结点
    101. //pTemp 代表要删除的结点
    102. NODE*pTemp = m_pHead;
    103. NODE*pFollow = nullptr;
    104. //3.2 用while循环找到需要删除结点的前一个结点
    105. //循环条件为:当结点元素不等于输入元素,循环执行;结点元素等于输入元素时,循环停止
    106. //pTemp此时并没有进入循环体,所以指向的仍为前一个结点
    107. while (pTemp != nullptr&&pTemp->nData != _In_nEle)
    108. {
    109. //pFollow为前一个结点
    110. pFollow = pTemp;
    111. //使pTemp移动到下一个结点(删除结点)
    112. pTemp = pTemp->pNext;
    113. }
    114. //3.3 如果没找到
    115. if (pTemp == nullptr)
    116. {
    117. //3.31 打印 "Element not found"
    118. cout << "Element not found" << endl;
    119. //3.32 返回错误码
    120. return Error_WrongEle;
    121. }
    122. //3.4 如果找到了
    123. else
    124. {
    125. //3.41 将前一个结点的pNext替代删除结点的pNext
    126. pFollow->pNext = pTemp->pNext;
    127. //3.42 再删除当前pTemp
    128. delete pTemp;
    129. }
    130. m_nLenth--;
    131. return Error_Success;
    132. }
    133. //4. 修改结点
    134. template <class T>
    135. ErrorCode CLinkList<T>::ModifyEleByLoc(int _In_nLoc, T _In_nEle)
    136. {
    137. //4.1 判断边界情况
    138. if (_In_nLoc < 0 || _In_nLoc >= m_nLenth)
    139. {
    140. cout << "Location not found";
    141. return Error_WrongLoc;
    142. }
    143. //4.2 遍历找到
    144. NODE*pTemp = m_pHead;
    145. for (int i = 0; i <= _In_nLoc; i++)
    146. {
    147. pTemp = pTemp->pNext;
    148. }
    149. //4.3 修改该结点
    150. pTemp->nData = _In_nEle;
    151. return Error_Success;
    152. }
    153. //5. 查找链表,通过位置nLoc输出nEle
    154. template <class T>
    155. T CLinkList<T>::GetEleByLoc(int nLoc, T& _Out_nEle)
    156. {
    157. //判断边界条件
    158. if (nLoc < 0 || nLoc >= m_nLenth)
    159. {
    160. return Error_WrongLoc;
    161. }
    162. //遍历通过位置查找到该结点
    163. NODE*pTemp = m_pHead;
    164. for (int i = 0; i <= nLoc; i++)
    165. {
    166. pTemp = pTemp->pNext;
    167. }
    168. return pTemp->nData;
    169. }
    170. //6. 清除链表
    171. template <class T>
    172. ErrorCode CLinkList<T>::ClearList()
    173. {
    174. NODE*pTemp = m_pHead;
    175. for (int i = 0; i < m_nLenth; i++)
    176. {
    177. //6.1 从第0个结点开始,将当前的结点赋给pFollow
    178. NODE*pFollow = pTemp;
    179. //6.2 pTemp移动到下一个结点
    180. pTemp = pTemp->pNext;
    181. //6.3 删除当前结点
    182. delete pFollow;
    183. }
    184. //6.4 循环完,再删除最后一个结点
    185. delete pTemp;
    186. m_pHead = nullptr;
    187. m_nLenth = 0;
    188. return Error_Success;
    189. }
    190. //7. 获取链表长度
    191. template <class T>
    192. int CLinkList<T>::GetLenth()
    193. {
    194. return m_nLenth;
    195. }