zoukankan      html  css  js  c++  java
  • 单向链表操作:新建,输出,删除,插入

    1.新建

    算法:使p1指向新开辟的结点,p2指向链表中最后一个结点,把p1所指的结点连接在p2所指结点的后面,用“p2->next=p1”来实现。

     1 #include<stdio.h>
     2 #include<stdlib.h>
     3 #include<malloc.h>
     4 
     5 #define LEN sizeof(struct student)
     6 
     7 struct student{
     8     long num;
     9     float score;
    10     struct student *next;
    11 };
    12 
    13 struct student *creat(void){
    14     struct student *head=NULL,*p1,*p2;
    15     int n=0;
    16 
    17     p1=(struct student *)malloc(LEN);
    18     p2=p1;
    19 
    20     printf("Input one student's data:
    ");
    21     scanf("%ld,%f",&p1->num,&p1->score);
    22     while(p1->num!=0)
    23     {
    24         n++;
    25         if(n==1)
    26             head=p1;
    27         else
    28             p2->next=p1;
    29         p2=p1;
    30         p1=(struct student *)malloc(LEN);
    31         printf("Input one student's data:
    ");
    32         scanf("%ld,%f",&p1->num,&p1->score);
    33     }
    34     p2->next=NULL;
    35     return head;
    36 }
    新建链表

    2.输出

    1 void print(struct student *head)
    2 {
    3     struct student *p;
    4     for(p=head;p!=NULL;p=p->next)
    5     {
    6         printf("%ld,%f
    ",p->num,p->score);
    7     }
    8 }
    输出链表

    3.删除

     这是我用for循环编写的:

     1 struct student *del(struct student *head,long num){
     2     struct student *p1,*p2;
     3     if(head==NULL)
     4         printf("The list is NULL.
    ");
     5     else
     6         for(p1=head;p1!=NULL;p1=p1->next)
     7         {
     8             if(p1->num==num)
     9             {
    10                 if(p1==head)
    11                     head=p1->next;
    12                 else
    13                     p2->next=p1->next;
    14                 break;
    15             }
    16             else
    17             {
    18                 p2=p1;
    19             }
    20         }
    21 
    22     if(p1==NULL)
    23         printf("cannot find the %ld.
    ",num);
    24     return head;
    25 }
    删除结点1

    书上用while循环编写的:

     1 struct student *del(struct student *head,long num){
     2     struct student *p1,*p2;
     3     if(head==NULL)
     4     {
     5         printf("The list is NULL.
    ");
     6         return head;
     7     }
     8     p1=head;
     9     while(p1->num!=num&&p1->next!=NULL)//当前结点不是要删除的结点而且后面还有结点。
    10     {
    11         p2=p1;
    12         p1=p1->next;
    13     }
    14     if(p1->num==num)
    15     {
    16         if(p1==head)
    17             head=p1->next;
    18         else
    19             p2->next=p1->next;
    20     }
    21     else
    22         printf("%ld cannot be found.
    ",num);
    23     return head;
    24 }
    删除结点2

     4.插入

    使用for循环编写:

     1 struct student *insert(struct student *head,struct student *stu){
     2     struct student *p0,*p1,*p2;
     3     p0=stu;
     4     for(p1=head;p1!=NULL;p1=p1->next)
     5     {
     6         if(p1->num < p0->num)
     7             p2=p1;
     8         else
     9         {
    10             if(p1==head)
    11                 head=p0;
    12             else
    13                 p2->next=p0;
    14             p0->next=p1;
    15             break;
    16         }
    17     }
    18     if(p1==NULL)
    19     {
    20         if(p1==head)
    21             head=p0;
    22         else
    23             p2->next=p0;
    24         p0->next=NULL;
    25     }
    26     return head;
    27 }
    插入结点1

    使用while循环编写:

     1 struct student *insert(struct student *head,struct student *stu){
     2     struct student *p0,*p1,*p2;
     3     p0=stu;
     4     if(head==NULL)
     5     {
     6         head=p0;
     7         p0->next=NULL;
     8     }
     9     else
    10     {
    11         p1=head;
    12         while(p1->num<p0->num&&p1->next!=NULL)
    13         {
    14             p2=p1;
    15             p1=p1->next;
    16         }
    17         if(p1->num>p0->num)
    18         {
    19             if(p1==head)
    20                 head=p0;
    21             else
    22                 p2->next=p0;
    23             p0->next=p1;
    24         }
    25         else
    26         {
    27             p1->next=p0;
    28             p0->next=NULL;
    29         }
    30     }
    31     return head;
    32 }
    插入结点2

    我刚开始用的函数原型是:

    struct student *insert(struct student *head)

    插入的结点在函数内部产生,事实证明这样做是不行的。因为插入的结点数据在函数调用完之后就释放了,没有保存。

    后来函数原型改为:

    struct student *insert(struct student *head,struct student stu)

    插入的结点在主函数内产生,经过一番试验后,发现也不对。新结点的数据传递给形参stu,形参stu有自己的地址,insert函数把形参stu连接在了链表中,函数调用完之后,形参stu的值就释放了,链表中新结点处的值为不确定的值。

    链表学习心得:在对链表进行操作的过程中,要设两个循环变量指针:p1和p2。其中p1指向当前要进行操作或处理的结点,p2指向当前结点的前一个结点,当前结点的后一个结点可以直接用p1->next表示。循环遍历数组的话,可以用p++和p--指向后一个元素和前一个元素,但是因为链表中的结点不是连续存放的,所以只能用设两个循环变量的方法遍历数组。

  • 相关阅读:
    Python解析库lxml与xpath用法总结
    安装docker时,遇到Loaded plugins...怎么办
    【AcWing】第6场周赛 B题 3734. 求和 (思维)
    CF上部分树形DP练习题
    Codeforces Round #481 (Div. 3) 经典几道思维题
    KB专题:区间DP专辑
    ZOJ 3537 Cake (凸包 + 区间DP && 最优三角形剖分)
    AtCoder Beginner Contest 171 AK!
    【算法学习笔记】分段打表
    [apue] 多进程管道读写的一些疑问
  • 原文地址:https://www.cnblogs.com/Camilo/p/3384498.html
Copyright © 2011-2022 走看看