• C++ 单向链表手动实现(课后作业版)


    单向链表,并实现增删查改等功能

    首先定义节点类,类成员包含当前节点的值和下一个节点的地址

    1. /node definition
    2. template <typename T>
    3. class Node {
    4. public:
    5. T value;
    6. Node* next;
    7. Node() {}
    8. Node(const T& value) {
    9. this->value = value;
    10. next = nullptr;
    11. }
    12. Node(const T& value, const Node& next) {
    13. this->value = value;
    14. this->next = next;
    15. }
    16. };

    然后是链表类的定义,主要包含了增删查改等功能

    1. //linklist definition
    2. template <typename T>
    3. class LinkList {
    4. public:
    5. Node* headnode;
    6. LinkList();
    7. LinkList(const T* arr, int len); //array initial
    8. LinkList(const LinkList& link);
    9. ~LinkList();
    10. LinkList& push_back(T n);
    11. LinkList& push_front(T n);
    12. LinkList& insert(int pos, int n, T* arr);
    13. LinkList& pop_front();
    14. LinkList& pop_back();
    15. LinkList& remove(int pos, int num);
    16. LinkList& reverse();
    17. T& operator[](int n);
    18. T& at(int n);
    19. LinkList& replace(int pos, int n, T* arr);
    20. int getLen() {return len;}
    21. void clear() {this->~LinkList();}
    22. void display();
    23. private:
    24. int len = 0;
    25. Node* getNode(int n);
    26. };

    各个函数解释:

    LinkList();      默认构造函数

    LinkList(const T* arr, int len);      一般构造函数

    LinkList(const LinkList& link)           拷贝构造函数

    ~LinkList();     析构函数

    LinkList& push_back(T n);    在尾部添加一个元素

    LinkList& push_front(T n);     在头部添加一个元素

    LinkList& insert(int pos, int n, T* arr);   在pos处插入n个元素

    LinkList& pop_front();    删除第一个节点

    LinkList& pop_back();    删除最后一个节点

    LinkList& remove(int pos, int num);     删除pos开始的num个元素

    LinkList& reverse();     反转链表

    T& operator[](int n);     重载[ ]运算符,返回第n个节点的值

    T& at(int n);                 与[ ]一样,只不过会检查索引是否越界

    LinkList& replace(int pos, int n, T* arr);    替换n个节点

    int getLen() {return len;}     返回长度,因为len是private

    void clear() {this->~LinkList();}    清除链表

    void display();    显示链表所有元素

    Node* getNode(int n);     返回第n个节点的指针,是private函数,在其他函数中经常用到

    最后是各个成员函数的定义:

    1. #include
    2. using namespace std;
    3. //node definition
    4. template <typename T>
    5. class Node {
    6. public:
    7. T value;
    8. Node* next;
    9. Node() {}
    10. Node(const T& value) {
    11. this->value = value;
    12. next = nullptr;
    13. }
    14. Node(const T& value, const Node& next) {
    15. this->value = value;
    16. this->next = next;
    17. }
    18. };
    19. //linklist definition
    20. template <typename T>
    21. class LinkList {
    22. public:
    23. Node* headnode;
    24. LinkList();
    25. LinkList(const T* arr, int len); //array initial
    26. LinkList(const LinkList& link);
    27. ~LinkList();
    28. LinkList& push_back(T n);
    29. LinkList& push_front(T n);
    30. LinkList& insert(int pos, int n, T* arr);
    31. LinkList& pop_front();
    32. LinkList& pop_back();
    33. LinkList& remove(int pos, int num);
    34. LinkList& reverse();
    35. T& operator[](int n);
    36. T& at(int n);
    37. LinkList& replace(int pos, int n, T* arr);
    38. int getLen() {return len;}
    39. void clear() {this->~LinkList();}
    40. void display();
    41. private:
    42. int len = 0;
    43. Node* getNode(int n);
    44. };
    45. //default constructor
    46. template <typename T>
    47. LinkList::LinkList() {
    48. headnode = nullptr;
    49. len = 0;
    50. }
    51. //normal constructor
    52. template <typename T>
    53. LinkList::LinkList(const T* arr, int len) {
    54. Node* temp = nullptr;
    55. Node* node = nullptr;
    56. if ( len < 0 ) {
    57. cout << "[error]: illegal length of LinkList" << endl;
    58. exit(0);
    59. }
    60. for ( int i = len-1; i >= 0; i-- ) {
    61. node = new Node(i);
    62. node->value = *(arr+i);
    63. node->next = temp;
    64. temp = node;
    65. node = nullptr;
    66. }
    67. headnode = temp;
    68. this->len = len;
    69. }
    70. //copy constructor
    71. template <typename T>
    72. LinkList::LinkList(const LinkList& link) {
    73. this->len = link.getLen();
    74. this->headnode = link.headnode;
    75. link.headnode = nullptr;
    76. }
    77. //deconstructor
    78. template <typename T>
    79. LinkList::~LinkList() {
    80. this->len = 0;
    81. Node* temp = headnode;
    82. while ( headnode ) {
    83. temp = headnode;
    84. headnode = headnode->next;
    85. delete temp;
    86. temp = nullptr;
    87. }
    88. }
    89. //display all elements in Linklist
    90. template <typename T>
    91. void LinkList::display() {
    92. if ( len == 0 ) {
    93. cout << "[warning]: can not disply empty linkedlist" << endl;
    94. return;
    95. }
    96. Node *node = headnode;
    97. for ( int i = 0; i < len; i++ ) {
    98. cout << node->value << " ";
    99. node = node->next;
    100. }
    101. cout << endl;
    102. }
    103. //add one node at the last position
    104. template <typename T>
    105. LinkList& LinkList::push_back(T n) {
    106. Node *node = this->getNode(len-1);
    107. if ( node->next == nullptr ) {
    108. Node *temp = new Node(n);
    109. node->next = temp;
    110. this->len++;
    111. }
    112. return *this;
    113. }
    114. //add one node at the first position
    115. template <typename T>
    116. LinkList& LinkList::push_front(T n) {
    117. Node* node_new = new Node(n);
    118. node_new->next = headnode;
    119. headnode = node_new;
    120. this->len++;
    121. return *this;
    122. }
    123. //insert elements to LinkList
    124. template <typename T>
    125. LinkList& LinkList::insert(int pos, int n, T* arr) {
    126. if ( pos > len-1 || len < 0 ) {
    127. cout << "[error]: illegal insert position, please check again" << endl;
    128. exit(0);
    129. }
    130. if ( pos == 0 ) {
    131. for ( int i = 0; i < n; i++ )
    132. this->push_front(arr[n-1-i]);
    133. return *this;
    134. }
    135. Node* node_N = getNode(pos-1); //前半部分
    136. Node* temp = node_N->next; //后半部分
    137. Node* node_new = nullptr; //新增加的
    138. for ( int i = 0; i < n; i++ ) {
    139. node_new = new Node (arr[n-1-i]);
    140. node_new->next = temp;
    141. temp = node_new;
    142. node_new = nullptr;
    143. }
    144. node_N->next = temp;
    145. this->len += n;
    146. return *this;
    147. }
    148. //delete the first element
    149. template <typename T>
    150. LinkList& LinkList::pop_front() {
    151. if ( this->len == 0 ) {
    152. cout << "[error]: LinkList don't has any element" << endl;
    153. exit(0);
    154. }
    155. Node* temp = headnode;
    156. headnode = getNode(1);
    157. delete temp;
    158. this->len--;
    159. return *this;
    160. }
    161. //delete the last element
    162. template <typename T>
    163. LinkList& LinkList::pop_back() {
    164. if ( this->len == 0 ) {
    165. cout << "[error]: LinkList don't has any element" << endl;
    166. exit(0);
    167. }
    168. Node* temp = getNode(len-2);
    169. delete temp->next;
    170. temp->next = nullptr;
    171. this->len--;
    172. return *this;
    173. }
    174. //get the last node pointer
    175. template <typename T>
    176. Node* LinkList::getNode(int n) {
    177. if ( n > len-1 || n < 0) {
    178. cout << "[error]: index out of range" <
    179. }
    180. Node *node = headnode;
    181. for( int i = 0; i < n; i++ ) {
    182. node = node->next;
    183. }
    184. return node;
    185. }
    186. //remove n elements
    187. template <typename T>
    188. LinkList& LinkList::remove(int pos, int num) {
    189. if ( pos > len-1 || len < 0 ) {
    190. cout << "[error]: illegal remove position, please check again" << endl;
    191. exit(0);
    192. } else if ( pos + num > len) {
    193. cout << "[error]: remove index out of range" << endl;
    194. exit(0);
    195. }
    196. if ( pos == 0 ) {
    197. for ( int i = 0; i < num; i++ )
    198. this->pop_front();
    199. return *this;
    200. }
    201. Node* node_N = getNode(pos-1);
    202. Node* node_N_num = getNode(pos+num);
    203. Node* temp = getNode(pos);
    204. while ( 1 ) {
    205. Node* node = temp;
    206. temp = temp->next;
    207. delete node;
    208. if ( temp == node_N_num ) {
    209. break;
    210. }
    211. }
    212. node_N->next = node_N_num;
    213. this->len -= num;
    214. return *this;
    215. }
    216. //reverse linklist
    217. template <typename T>
    218. LinkList& LinkList::reverse() {
    219. Node* front = nullptr;
    220. Node* mid = headnode;
    221. Node* back = headnode->next;
    222. while ( back ) {
    223. mid->next = front;
    224. front = mid;
    225. mid = back;
    226. back = back->next;
    227. }
    228. mid->next = front;
    229. front = nullptr;
    230. headnode = mid;
    231. return *this;
    232. }
    233. template <typename T>
    234. T& LinkList::operator[](int n) {
    235. if ( n > len-1 || n < 0 ) {
    236. cout << "[error]: index out of range" << endl;
    237. exit(0);
    238. }
    239. return this->getNode(n)->value;
    240. }
    241. template <typename T>
    242. LinkList& LinkList::replace(int pos, int n, T* arr) {
    243. if ( pos > len-1 || len < 0 ) {
    244. cout << "[error]: illegal remove position, please check again" << endl;
    245. exit(0);
    246. } else if ( pos + n > len) {
    247. cout << "[error]: remove index out of range" << endl;
    248. exit(0);
    249. }
    250. Node* temp = nullptr;
    251. if ( pos == 0 )
    252. temp = headnode;
    253. else
    254. temp = this->getNode(pos-1);
    255. for ( int i = 0; i < n; i++ ) {
    256. temp->value = arr[i];
    257. temp = temp->next;
    258. }
    259. return *this;
    260. }
    261. int main(){
    262. int arr[]{1,2,4,5,0};
    263. LinkList<int> link(arr, sizeof(arr)/sizeof(int));
    264. cout << "LinkLint init with arr: " <
    265. link.display();
    266. cout << "push_back:" << endl;
    267. link.push_back(34);
    268. link.display();
    269. cout << "push_front:" << endl;
    270. link.push_front(10);
    271. link.display();
    272. cout << "insert:" << endl;
    273. link.insert(0,4,arr);
    274. link.display();
    275. cout << "pop_front:" << endl;
    276. link.pop_front();
    277. link.display();
    278. cout << "pop_back:" << endl;
    279. link.pop_back();
    280. link.display();
    281. cout << "remove:" << endl;
    282. link.remove(2,3);
    283. link.display();
    284. cout << "[] operator:" << endl;
    285. cout << link[2] << endl;
    286. cout << "replace:" << endl;
    287. int a[] = {6,5,2};
    288. link.replace(2, sizeof(a)/sizeof(int), a);
    289. link.display();
    290. cout << "linklist reserve:" << endl;
    291. link.reverse();
    292. link.display();
    293. cout << "clear:" << endl;
    294. link.clear();
    295. cout << "len=" << link.getLen() << endl;
    296. link.display();
    297. }


     

  • 相关阅读:
    后端微服务项目中出现的问题整理2022年11月
    TogoID - 生物医学数据库ID转换工具
    SSM+智慧养老服务平台 毕业设计-附源码211709
    深度适配云环境,火山引擎推出云操作系统veLinux
    Linux修改认证加密方式为sha512
    最强大脑(4)
    Linux Socket网络编程UDP、TCP 阻塞与非阻塞 断线重连机制
    自然语言处理——基础篇01
    NVR(网络硬盘录像机)以及其他相近名词DVR、DVS、NVS
    如何读取照片的GPS信息?—最好的语言Java实现起来就这么简单【手把手教程+完整代码】
  • 原文地址:https://blog.csdn.net/a1367666195/article/details/127965774