链表 Linked List

打印 上一主题 下一主题

主题 899|帖子 899|积分 2697

2024.3.15
芝士wa
参考视频:bilibli-数据结构-链表
  “印度小哥讲得真好”
链表


  • 对于链表来说,存储数据需要两个部门,一是数据本身,二是指针,该指针指向下一个数据的地址,依次链接,直到末了一个元素,指针指向空(NULL)


  • 遍历的时间复杂度为O(n)
  • 插入的时间复杂度为O(n)
  • 删除的时间复杂度为O(n)
链表VS数组


  • 数组是连续存储空间,链表通过指针维系,存储数据并不连续
  • 数组可以通过下标访问元素,只需要O(1)的时间复杂度,而链表则必须按照顺序访问,因此时间复杂度为O(n/2) = O(n)
  • 数组的大小是固定的,在创建数组时确认
  • 上风:链表在添加或删除元素时,制止了不相关元素的复制移动,空间复杂度较小
  • 使用链表时,要格外注意指针问题
链表的C++实现

完整代码
  1. #pragma once
  2. #include <iostream>
  3. using namespace std;
  4. template<class T>
  5. class Node
  6. {
  7. public:
  8.         T data;
  9.         Node* next;
  10. };
  11. template<class T>
  12. class LinkedList
  13. {
  14. public:
  15.         LinkedList();
  16.         ~LinkedList();
  17.         Node<T>* head;
  18.        
  19.         int m_num;//记录节点个数
  20.         //尾插法
  21.         void Insert(T x);
  22.         //在特定位置添加
  23.         void Insert(T x, int n);
  24.         //打印,遍历法
  25.         void print();
  26.         //递归方法打印
  27.         void Rprint(Node<T>* p);
  28.         //特定位置删除
  29.         void remove(int n);
  30.         //反转链表,迭代法
  31.         void reverse();
  32.         //反转链表,递归方法
  33.         void Reverse(Node<T>* p);
  34. };
  35. template<class T>
  36. LinkedList<T>::LinkedList()
  37. {
  38.         head = new Node<T>;
  39.         head->next = NULL;
  40.         this->m_num = 0;
  41. }
  42. template<class T>
  43. LinkedList<T>::~LinkedList()
  44. {
  45.         Node<T>* ite = head;
  46.         Node<T>* next;
  47.         while (ite != NULL) {
  48.                 next = ite->next;
  49.                 delete ite;
  50.                 ite = next;
  51.         }
  52.         this->m_num = 0;
  53. }
  54. template<class T>//尾插法添加元素
  55. void LinkedList<T>::Insert(T x)
  56. {
  57.         Node<T>* end = new Node<T>;
  58.         end->data = x;
  59.         end->next = NULL;
  60.         if (head== NULL) {
  61.                 //链表为空
  62.                 head = end;
  63.                 this->m_num++;
  64.                 cout << "添加成功,当前节点数量:" << this->m_num << endl;
  65.         }
  66.         else {
  67.                 Node<T>* ite = head;
  68.                 //链表不为空,得到末尾end
  69.                 while (ite->next != NULL) {
  70.                         ite = ite->next;
  71.                 }
  72.                 //现在ite指向最后一个元素
  73.                 ite->next = end;
  74.         }
  75.         this->m_num++;
  76.         cout << "添加成功,当前节点数量:" << this->m_num << endl;
  77. }
  78. template<class T>//特定位置添加元素
  79. void LinkedList<T>::Insert(T x, int n)
  80. {
  81.         Node<T>* temp = new Node<T>;
  82.         temp->data = x;
  83.         temp->next = NULL;
  84.         if (n == 1) {
  85.                 //在头节点之后添加
  86.                 temp->next = head->next;
  87.                 head = temp;
  88.                 this->m_num++;
  89.                 cout << "添加成功,当前节点数量:" << this->m_num << endl;
  90.                 return;
  91.         }
  92.         else if(n > 1 && n <= this->m_num){
  93.                 Node<T>* ite = head;
  94.                 //找到第n-1个元素,
  95.                 for (int i = 0; i <= n - 2; i++) {
  96.                         ite = ite->next;
  97.                 }
  98.                 temp->next = ite->next;
  99.                 ite->next = temp;
  100.                 this->m_num++;
  101.                 cout << "添加成功,当前节点数量:" << this->m_num << endl;
  102.                 return;
  103.         }
  104.         else {
  105.                 cout << "越界" << endl;
  106.                 return;
  107.         }
  108. }
  109. template<class T>
  110. void LinkedList<T>::print()
  111. {
  112.         Node<T>* ite = head;
  113.         while (ite!= NULL) {
  114.                 cout << ite->data << "\t";
  115.                 ite = ite->next;
  116.         }
  117.         cout << endl;
  118. }
  119. template<class T>
  120. void LinkedList<T>::Rprint(Node<T> * p)
  121. {
  122.         if (p == NULL) {
  123.                 return;
  124.         }
  125.         Rprint(p->next);
  126.         cout << p->data << "\t";
  127. }
  128. template<class T>
  129. void LinkedList<T>::remove(int n)
  130. {
  131.         Node<T>* temp = head;
  132.         //第一个节点
  133.         if (n == 1) {
  134.                 head = head->next;
  135.                 delete temp;
  136.                 this->m_num--;
  137.                 cout << "删除成功,当前节点数量:" << this->m_num << endl;
  138.                 return;
  139.         }
  140.         //第2~num之间删除节点
  141.         else if (n > 1 && n <= this->m_num) {
  142.                 for (int i = 0; i < n - 2; i++) {
  143.                         temp = temp->next;
  144.                 }
  145.        
  146.                 //现在temp指向的是第n-1个节点
  147.                 Node<T>* temp1 = temp->next;//指向第n个
  148.                 temp->next = temp1->next;
  149.                 delete temp1;
  150.                 this->m_num--;
  151.                 cout << "删除成功,当前节点数量:" << this->m_num << endl;
  152.                 return;
  153.         }
  154.         else {
  155.                 cout << "越界" << endl;
  156.                 return;
  157.         }
  158.        
  159. }
  160. template<class T>
  161. void LinkedList<T>::reverse()
  162. {
  163.         Node<T>* current, * prev, * next;
  164.         current = head;
  165.         prev = NULL;
  166.         while (current != NULL) {
  167.                 next = current->next;
  168.                 current->next = prev;
  169.                 prev = current;
  170.                 current = next;
  171.         }
  172.         head = prev;
  173. }
  174. template<class T>
  175. void LinkedList<T>::Reverse(Node<T>* p)
  176. {
  177.         if (p->next == NULL) {
  178.                 head = p;
  179.                 return;
  180.         }
  181.         Reverse(p->next);
  182.         p->next->next = p;
  183.         p->next = NULL;
  184. }
复制代码

  • 模板,泛型
  • 内部维护链表长度
  • 分别用递归和迭代的方式实现了打印和反转
  • 进行了简单的越界判定处置惩罚



双向链表

  1. template<class T>
  2. class Node
  3. {
  4.   T data;
  5.   Node* prev;
  6.   Node* next;
  7. };
复制代码
总结

本文先容了链表的概念和特性,并用C++实现了单链表。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

熊熊出没

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表