• 单链表的基本操作


    目录

    1 链表的引入

    2 链表的动态遍历

    3 遍历链表中的p = p - next

    4 统计链表的个数

    5 查找指定的节点

    6 从指定节点后方插入新节点

    7   从指定节点前方插入新节点


    1 链表的引入

         链表的每个节点由数据域指针域构成。数据域存放数据元素信息,指针域存放后继节点的地址。最后一个节点是没有后继节点,因此其指针域一般设置为NULL。

     链表与数组的区别?

         数组是线性存储结构,在内存地址是连续的,增加一个数组元素和删除一个数组元素都是非常不方便;而链表是链式存储结构,在内存空间中地址不一定是连续的,因为地址不连续所以插入一个节点或者删除一个节点都是非常方便,可以看出链表比较灵活。

    如何使用链表存放三个整数1,2,3 ?

    1. #include
    2. struct Test{
    3. int data;
    4. struct Test *next;
    5. };
    6. int main(void)
    7. {
    8. /*申明了三个节点,存放数据1,2,3;但是这三个
    9. 节点之间并没有联系,因为他们的指针域并没有存放
    10. 后继节点的地址*/
    11. struct Test t1 = {1, NULL};
    12. struct Test t2 = {2, NULL};
    13. struct Test t3 = {3, NULL};
    14. /*让指针存放后继节点的地址*/
    15. t1.next = &t2;
    16. t2.next = &t3;
    17. /*现在通过变量t1就可以访问到t2,t3里面的数据*/
    18. printf("t1 = %d\nt2 = %d\nt3 = %d\n",t1.data,t1.next->data,t1.next->next->data);
    19. return 0;
    20. }

    2 链表的动态遍历

         链表的最后一个节点是没有后继节点;因此可以通过判断当前节点的指针是否为NULL来遍历循环链表。

    1. struct Test *print_link(struct Test *head)
    2. {
    3. struct Test *temp = head;
    4. while(temp)//因为最后一个节点是没有后继节点的,所以可以通过判断后继节点是否为NULL来遍历链表
    5. {
    6. printf("%d\n",temp->data);
    7. temp = temp->next; //让temp指向后继节点
    8. }
    9. }

    3 遍历链表中的p = p - next

    4 统计链表的个数

         在动态遍历链表的时候,设置一个计算器变量i;通过i来统计链表的个数

    1. int Get_link_nodeNum(struct Test *head)
    2. {
    3. struct Test *temp = head;
    4. int i = 0;
    5. while(temp)
    6. {
    7. i++;
    8. temp = temp->next;
    9. }
    10. return i;
    11. }

    5 查找指定的节点

         在动态遍历链表的时候,判断当前节点的数据是否等于我们所需要的数据;如果查找到了我们所需要的数据让函数返回该节点的地址;如果未查找到让函数返回NULL;

    1. struct Test *findNode_byDate(struct Test *head,int data)
    2. {
    3. struct Test *temp = head;
    4. while(temp)
    5. {
    6. if(temp->data = data)
    7. {
    8. printf("找到data=%d的指定节点\n",data);
    9. return temp;
    10. }
    11. temp = temp->next;
    12. }
    13. printf("未找到data=%d的指定节点\n",data);
    14. return NULL;
    15. }

    6 从指定节点后方插入新节点

     

    如上图所示在指定节点的后方插入,共分为三步:

    1 找到指定的节点p

    2 将新节点new的后继节点设置为指定节点的后继节点,即new->next = p ->next;

    3 将指定节点的后继节点设置为新节点,即p->next = new;         

       如果插入成功,提示插入成功并返回1;插入失败,提示插入失败并返回0;

    1. int insertNode_Rear(struct Test *head,struct Test *new,int data)
    2. {
    3. struct Test *temp = head;
    4. while(temp)
    5. {
    6. if(temp->data = data)
    7. {
    8. new->next = temp->next;
    9. temp->next = new;
    10. printf("插入成功\n");
    11. return 1;
    12. }
    13. temp = temp->next;
    14. }
    15. printf("未找到指定节点,插入失败!\n");
    16. return 0;
    17. }

    7  从指定节点前方插入新节点

    情况1:

    如果指定节点是头节点,让新节点的后继节点设置为头节点,即new->next = head;此时新节点变成了头节点,所以要让head = new。

    情况2:

    如果指定节点不是头节点,则通过判断头节点下一个节点是否是否我们需要找的指定节点(通过p->next->data == data来判断);

    1. struct Test *insertNode_front(struct Test *head,struct Test *new,int data)
    2. {
    3. struct Test *temp = head;
    4. if(temp->data == data)
    5. {
    6. new->next = temp;
    7. head = new;
    8. return new;
    9. }
    10. while(temp->next != NULL)
    11. {
    12. if(temp->next->data == data)
    13. {
    14. new-next = temp->next;
    15. temp->next = new;
    16. return head;
    17. }
    18. temp = temp->next;
    19. }
    20. printf("找不到指定data=%d的节点,插入失败!\n",data);
    21. return NULL;
    22. }

     8 链表删除指定节点

     情况1:

    如果删除的节点是头节点,让头节点直接指向第二个节点,即head = head->next;

    情况2:

    如果删除的节点不是头节点, 则通过判断头节点下一个节点是否是我们需要找的删除的节点(通过p->next->data == data来判断);

        如果是使用malloc开辟的空间,在删除节点后需要及时使用free( )函数进行释放,否则会造成内存泄漏。

    1. struct Test *deleteNode(struct Test *head, int data)
    2. {
    3. struct Test *temp = head;
    4. struct Test *temp_free = NULL; //用来存放删除的节点,以便使用free()函数释放内存
    5. if(temp->data == data)
    6. {
    7. //temp_free = temp;
    8. temp = temp->next;
    9. // free(temp_free);
    10. return temp;
    11. }
    12. else
    13. {
    14. while(temp->next != NULL)
    15. {
    16. if(temp->next->data == data)
    17. {
    18. //temp_free = temp->next;
    19. temp->next = temp->next->next;
    20. //free(temp_free);
    21. return head;
    22. }
    23. p = p->next;
    24. }
    25. }
    26. return head;
    27. }

    9 头插法创建链表

            让新节点的后继节点设置原来的头节点,即new->next = head;让后将头节点设置为新节点,即head = new

    1. struct Test *create_front(struct Test *head)
    2. {
    3. struct Test *new;
    4. int i,n;
    5. printf("请输入要插入的节点个数:\n");
    6. scanf("%d",&n);
    7. if(head == NULL)
    8. {
    9. head = (struct Test*)malloc(sizeof(struct Test));
    10. printf("请输入数据:\n");
    11. scanf("%d",&head->data);
    12. head->next = NULL;
    13. n = n - 1;
    14. }
    15. for(i = 0;i < n;i++)
    16. {
    17. new = (struct Test*)malloc(sizeof(struct Test));
    18. printf("请输入数据:\n");
    19. scanf("%d",&new->data);
    20. new->next = head;
    21. head = new;
    22. }
    23. return head;
    24. }

    10 尾插法创建链表

        定义一个尾节点tail,刚刚开始tail = head;然后动态遍历到尾节点,让尾节点的后继节点设置为新节点,即tail->next = new;同时尾节点设置为新节点,即tail = new;

    1. struct Test *create_rear(struct Test *head)
    2. {
    3. int n,i;
    4. struct Test *new;
    5. struct Test *tail;
    6. printf("请输入插入的节点个数:\n");
    7. scanf("%d",&n);
    8. if(head == NULL)
    9. {
    10. head =(struct Test*)malloc(sizeof(struct Test));
    11. printf("请输入数据:\n");
    12. scanf("%d",&head->data);
    13. n = n-1;
    14. head->next = NULL;
    15. }
    16. tail = head;
    17. //遍历至尾节点
    18. while(tail->next != NULL)
    19. {
    20. tail = tail->next;
    21. }
    22. for(i = 0;i < n; i++)
    23. {
    24. new = (struct Test*)malloc(sizeof(struct Test));
    25. printf("请输入数据:\n");
    26. scanf("%d",&new->data);
    27. tail->next = new;
    28. tail = new;
    29. }
    30. return head;
    31. }

     

            

                                                    

  • 相关阅读:
    关于DatagridviewComboBox控件的若干技术问题
    C/C++编译器配置——MinGW下载安装
    c++builder 6.0 使用TRichView最基本的方法
    Windows右键菜单美化(适用版本:Win7-Win11) 奇怪的美化教程 #1
    DC进阶-多周期约束详解
    苏宁API接口
    selenium(练习)提取dou yu网站上的数据
    使用宝塔部署项目
    Vue3 数据响应式原理:Proxy和Reflect
    如何选择安全可靠的跨网文件安全交换一体机?
  • 原文地址:https://blog.csdn.net/qq_55299368/article/details/126002301