• 链表的基本操作


    (一)实验类型:设计性

    (二)实验目的:

          1. 掌握线性表的链式存贮结构及基本操作,深入了解链表的基本特性,以便在实际问题背景下灵活运用它们

          2. 巩固该存贮结构的构造方法,深入理解和灵活掌握链表的插入、删除等操作

    (三)实验内容:

    1. 建立线性表的链式存储结构。

    2. 完成链表操作:建立,初始化,增加,插入,删除。

     

    1. #include
    2. // 链表节点结构
    3. struct ListNode {
    4. int val; // 节点存储的值
    5. ListNode* next; // 指向下一个节点的指针
    6. };
    7. // 初始化链表
    8. void initList(ListNode*& head) {
    9. head = nullptr;
    10. }
    11. // 在链表尾部添加节点
    12. void appendNode(ListNode*& head, int value) {
    13. ListNode* newNode = new ListNode; // 创建新节点
    14. //创建新的空间
    15. newNode->val = value;
    16. newNode->next = nullptr;
    17. if (head == nullptr) {
    18. head = newNode; // 如果链表为空,直接将新节点作为头节点
    19. }
    20. else {
    21. ListNode* tmp = head;
    22. while (tmp->next != nullptr) {
    23. tmp = tmp->next; // 遍历链表,找到尾部节点
    24. }
    25. tmp->next = newNode; // 将新节点连接到尾部节点的next指针上
    26. }
    27. }
    28. // 在指定位置插入节点
    29. void insertNode(ListNode*& head, int value, int pos) {
    30. if (pos <= 0) {
    31. ListNode* newNode = new ListNode; // 创建新节点
    32. newNode->val = value;
    33. newNode->next = head; // 将新节点连接到头节点之前
    34. head = newNode; // 将新节点作为头节点
    35. }
    36. else {
    37. ListNode* tmp = head;
    38. int count = 1;
    39. while (tmp != nullptr && count < pos)
    40. //tmp != nullptr是因为我们插入是必须要左右两边都有数据才能叫插入,
    41. //不然就只能添加,不可以直接填在一个很远的空间里,不然就浪费空间了
    42. {
    43. tmp = tmp->next; // 遍历链表,找到指定位置的前一个节点
    44. count++;
    45. }
    46. if (tmp != nullptr)
    47. //必须是在tmp不为空时,才能算成插入。
    48. //再次判断是因为我们只选取count遍历到pos的位置的这种情况,而不是空的链表的情况。
    49. {
    50. ListNode* newNode = new ListNode; // 创建新节点
    51. newNode->val = value;
    52. newNode->next = tmp->next; // 将新节点连接到当前节点的next指针上
    53. //这是链接步骤的代码,把数据插入
    54. //至于next是因为我们是要插入在数据的中间,也就是tmp的next的位置
    55. tmp->next = newNode;
    56. //这个是指向新的插入数据的步骤,方便下一次数据的插入。
    57. }
    58. else {
    59. std::cout << "插入位置超过链表长度!" << std::endl;
    60. }
    61. }
    62. }
    63. // 删除指定位置的节点
    64. void deleteNode(ListNode*& head, int pos) {
    65. if (head == nullptr) {
    66. std::cout << "链表为空,无法删除节点!" << std::endl;
    67. return;
    68. }
    69. if (pos <= 0) {
    70. ListNode* tmp = head;
    71. head = head->next; // 删除头节点
    72. delete tmp;
    73. }
    74. else {
    75. ListNode* tmp = head;
    76. int count = 1;
    77. while (tmp->next != nullptr && count < pos) {
    78. tmp = tmp->next; // 遍历链表,找到指定位置的前一个节点
    79. count++;
    80. }
    81. if (tmp->next != nullptr) {
    82. ListNode* delNode = tmp->next;//先指向当前数据
    83. tmp->next = delNode->next;
    84. //直接将当前数据跳到下一个,前面已经链接好的数据不会丢失因为都在同一个位置
    85. //我们不过是把当前数据覆盖成下一个罢了
    86. delete delNode;
    87. }
    88. else {
    89. std::cout << "删除位置超过链表长度!" << std::endl;
    90. }
    91. }
    92. }
    93. // 打印链表
    94. void printList(ListNode* head) {
    95. ListNode* tmp = head;
    96. while (tmp != nullptr) {
    97. std::cout << tmp->val << " ";
    98. tmp = tmp->next;
    99. }
    100. std::cout << std::endl;
    101. }
    102. int main() {
    103. ListNode* myList;
    104. initList(myList);
    105. // 在链表尾部增加节点
    106. appendNode(myList, 1);
    107. appendNode(myList, 2);
    108. appendNode(myList, 3);
    109. printList(myList); // 输出:1 2 3
    110. // 在指定位置插入节点
    111. insertNode(myList, 4, 2);
    112. printList(myList); // 输出:1 4 2 3
    113. // 删除节点
    114. deleteNode(myList, 2);
    115. printList(myList); // 输出:1 2 3
    116. return 0;
    117. }

  • 相关阅读:
    集成AGC崩溃服务如何生成iOS符号文件表并上传
    Vue 路由 使用
    C++基础——结构体
    (Apache) Commons Lang3 Bridge For Scala 0.0.1 发布
    【数据结构】模拟实现LinkedList
    为什么要选低代码开发平台
    #systemverilog# 关键字之 `include(3)`include vs import 用法区别
    [C语言基础]文件读取模式简析
    STM8的C语言编程(3)+――+GPIO输出
    java8新特性(上)-Lambda表达式
  • 原文地址:https://blog.csdn.net/ASBSIHD/article/details/133658348