• 数据结构-单链表操作


    1、插入操作

            (1)创建一个新的要插入的结点

            (2)将新结点的 next 指针指向插入位置后的结点

            (3)将插入位置前的节点指针 next 指向新的结点

     注意:步骤(2)(3)的顺序不能颠倒,否则会导致插入位置后的部分链表丢失。

    插入位置一共分三种,分别是头部插入、中间插入和尾部插入。

            如图:

    代码:

    1. link* insertElem(link* p,int elem,int pos){
    2. link* temp = p;//创建临时结点temp
    3. //首先找到插入位置的上一个结点
    4. for(int i=1;i
    5. temp=temp->next;
    6. if(temp==NULL){
    7. printf("插入位置无效\n");
    8. return p;
    9. }
    10. }
    11. //创建插入结点c
    12. link *c=(link*)malloc(sizeof(link));
    13. c->elem=elem;
    14. //向链表中插入结点
    15. c->next = temp->next;
    16. temp->next=c;
    17. return p;
    18. }

     

    2、删除操作

            (1)将结点从链表中摘下

                    temp->next=temp->next->next

            (2)手动释放掉结点,回收被结点占用的存储空间

                    如图:

     代码:

    1. link*delElem(link*p,int pos){//p是原链表,pos是要删除的元素值
    2. link* temp=p;
    3. //遍历到被删除结点的上一个结点
    4. for(int i =1;i
    5. temp=temp->next;
    6. if(temp->next==NULL){
    7. printf("没有该结点\n");
    8. return p;
    9. }
    10. }
    11. link*del=temp->next;//单独开辟一块空间存放被删结点
    12. temp->next=temp->next->next;//从链表中摘除被删结点
    13. free(del);//手动释放该结点防止内存泄漏
    14. return p;
    15. }

    3、查找操作

            从头遍历链表。

    1. int searchElem(link* p,int elem){
    2. //新建一个指针t,初始化为头指针 p
    3. link*t=p;
    4. int i=1;
    5. //由于头节点的存在,因此while中的判断为t->next
    6. while(t->next){
    7. t=t->next;
    8. if(t->elem==elem){
    9. return i;
    10. }
    11. i++;
    12. }
    13. //程序执行至此处,表示查找失败
    14. return -1;
    15. }

    4、修改操作

             先找到目标位置再更改结点的数据域。

    1. link* changeElem(link* p,int pos,int newElem){
    2. link* temp=p;
    3. temp=temp->next;//在遍历之前,temp指向首元结点
    4. //遍历到待更新结点
    5. for(int i=1;i
    6. temp=temp->next;
    7. }
    8. temp->elem=newElem;
    9. return p;
    10. }

    5、完整代码:

    1. #include
    2. #include
    3. typedef struct Link{
    4. int elem;//数据域
    5. struct Link *next;//指针域,用来连接后继元素
    6. }link;//link为节点名,每个结点都是一个link结构体
    7. link* initLink(){
    8. link *p=(link*)malloc(sizeof(link));//创建头结点
    9. link*temp = p;//声明一个指针temp指向头结点,也就是头结点的地址赋值给指针变量(注意这不是头指针而是用来连接数组的临时指针变量)
    10. //生成链表
    11. for(int i=1;i<5;i++)
    12. {
    13. link *a=(link*)malloc(sizeof(link));//生成一个结点
    14. a->elem=i;//给结点的数据域赋值
    15. a->next=NULL;//指针域设置为空
    16. temp->next=a;//上一个结点的指针指向新增结点
    17. temp=temp->next;//临时指针向后移动也可写成temp=a
    18. }
    19. //返回头结点,通过头节点的指针即可找到整个链表
    20. return p;
    21. }
    22. link* insertElem(link* p,int elem,int pos){
    23. link* temp = p;//创建临时结点temp
    24. //首先找到插入位置的上一个结点
    25. for(int i=1;i
    26. temp=temp->next;
    27. if(temp==NULL){
    28. printf("插入位置无效\n");
    29. return p;
    30. }
    31. }
    32. //创建插入结点c
    33. link *c=(link*)malloc(sizeof(link));
    34. c->elem=elem;
    35. //向链表中插入结点
    36. c->next = temp->next;
    37. temp->next=c;
    38. return p;
    39. }
    40. link* delElem(link*p,int pos){//p是原链表,pos是要删除的元素值
    41. link* temp=p;
    42. //遍历到被删除结点的上一个结点
    43. for(int i =1;i
    44. temp=temp->next;
    45. if(temp->next==NULL){
    46. printf("没有该结点\n");
    47. return p;
    48. }
    49. }
    50. link*del=temp->next;//单独开辟一块空间存放被删结点
    51. temp->next=temp->next->next;//从链表中摘除被删结点
    52. free(del);//手动释放该结点防止内存泄漏
    53. return p;
    54. }
    55. link* changeElem(link* p,int pos,int newElem){
    56. link* temp=p;
    57. temp=temp->next;//在遍历之前,temp指向首元结点
    58. //遍历到待更新结点
    59. for(int i=1;i
    60. temp=temp->next;
    61. }
    62. temp->elem=newElem;
    63. return p;
    64. }
    65. int searchElem(link* p,int elem){
    66. //新建一个指针t,初始化为头指针 p
    67. link*t=p;
    68. int i=1;
    69. //由于头节点的存在,因此while中的判断为t->next
    70. while(t->next){
    71. t=t->next;
    72. if(t->elem==elem){
    73. return i;
    74. }
    75. i++;
    76. }
    77. //程序执行至此处,表示查找失败
    78. return -1;
    79. }
    80. void display(link *p){
    81. link*temp=p;//将temp指向头结点
    82. printf("链表中的数据为 : ");
    83. //只要temp指针指向的结点的next不是Null,就执行输出语句。
    84. while(temp->next){
    85. temp=temp->next;
    86. printf("%d ",temp->elem);
    87. }
    88. printf("\n");
    89. }
    90. int main()
    91. {
    92. //初始化链表
    93. link *p = initLink();
    94. display(p);
    95. printf("在第4的位置插入元素5:\n");
    96. p = insertElem(p, 5, 4);
    97. display(p);
    98. printf("删除元素3:\n");
    99. p = delElem(p, 3);
    100. display(p);
    101. printf("查找元素2的位置为:\n");
    102. int address = searchElem(p, 2);
    103. if (address == -1) {
    104. printf("没有该元素");
    105. }
    106. else {
    107. printf("元素2的位置为:%d\n", address);
    108. }
    109. printf("更改第3的位置上的数据为7:\n");
    110. p = changeElem(p, 3, 7);
    111. display(p);
    112. return 0;
    113. }

    输出结果:

     

  • 相关阅读:
    【深入设计模式】建造者模式—带你彻底弄懂建造者模式
    SpringMVC常用注解
    深度优先搜索实现抓牛问题
    接口自动化测试_L1
    前端新手导航页--vue3--vue3-tour使用
    如何处理linux 自动执行的sh脚本
    cmake中配置了工具链,命令行工具可以找到,但是clion中找不到
    微擎模块 家政服务小程序V2.7.1全开源解密版,一款专注于家政O2O行业的家政服务类小程序源码
    零基础搭建个人网站详细流程
    【苹果家庭推送】这是iPhone上SMS功能的严重安全漏洞
  • 原文地址:https://blog.csdn.net/qq_51701007/article/details/126009653