C&C++   发布时间:2022-04-13  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了链表的动态建立,插入、删除节点学习记录大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

 

(一)单向链表的动态建立

   假设有如下情景:用一个函数实现创建3个学生的数据的动态链表,包含学生的学号num、成绩score;   

    思路

链表的动态建立,插入、删除节点学习记录

 

 

 

    (1)先定义3个变量,head,p1,p2;然后用malloc函数开辟一个节点,让p1、p2两个指针指向这个节点。

     (2)从键盘上读取一个学生的数据赋值给这个节点。在此约定学号不能为0,当输入学号为0时候,则代表建立链表结束。

     (3)如果这个输入的p1->num!=0,则代表输入的是第一个节点把这个节点给头指针。即head=p1; 如上图所示

 

链表的动态建立,插入、删除节点学习记录

 

 

 

 

       (4)然后再开辟另一个节点,并使得p1指向它,接着从键盘输入数据,如果从键盘的读取到数还是不为0,那么该节点有效。如上图所示

链表的动态建立,插入、删除节点学习记录

 

 

 

 

     (5)把p1的值赋值给p2->next, 即p2->next=p1; 那么现在两个节点就连到一起了。如上图所示

链表的动态建立,插入、删除节点学习记录

 

 

 

     (6)接着把P2=p1,这样p2就跟上了p1的步伐了,可以开始下一次同样的操作;  如上图所示如上图所示

链表的动态建立,插入、删除节点学习记录

 

 

 

       (7)再开辟一个新节点,并使得p1指向它,如果num不为0,那么就吧p1赋值给p2->next,这样3个节点就连接到一起了。如上图所示

链表的动态建立,插入、删除节点学习记录

 

 

 

     (8)以此类推,知道最后输入的num 为0 ,建立结束。如上图所示

 

更为具体代码如下:

//动态链表的创建;
#include<stdio.h>
#include<stdlib.h>
#define LEN sizeof(struct student)
struct student   //结构体声明
{
    int num;
    float score;
    struct student* next;
};
int n;
struct student   *creat(void)
{
    struct student* head,*p1,*p2;                                    //定义三个指针;
    n = 0; head = NULL;                                             //头指针初始化为NULL;
    p1 = p2 = (struct student*)@H_354_166@malloc(LEN); //开辟一个节点,让p1 p2都指向它;
    scanf_s("%ld,%f", &p1->num, &p1->score); //给这个节点赋值;
    
    while (p1->num != 0)                 //当这个节点的num不为0的时候,说明此节点有效
    {
        n = n + 1;                       //节点数加1;
        if (n == 1) head = p1;           //如果这是第一个节点,那么就让头指针指向它;
        else p2->next = p1;              //如果不是第一个节点,就让p2指向它,此时的p2是上一个节点的指针;
        p2 = p1;                         //之后,让P2跟上P1的步伐,现在p1和p2都指向新的节点了;
        p1= (struct student*)@H_354_166@malloc(LEN);//开辟一个 新新的节点,让p1指向它,重复之前的步骤
        scanf_s("%ld,%f", &p1->num, &p1->score);//输入给新新节点的数据;
    }
    p2->next = NULL;                //退出while循环的条件是p1->num=0;说明链表建立结束了,之后把P2的后驱指为null即可;

    return head;     //返回头指针;
}
int main()
{
    struct student* pt;
    pt = creat();
    printf("\nnum:%ld\nscore:%5.1f\n", pt->num, pt->score);
    return 0;
}

 

(二)链表的删除节点

       知道了链表的建立,那么如何删除这个节点呢?

现在我们指定一个学号,删除该学号的学生;

   思路:

链表的动态建立,插入、删除节点学习记录

 

 

 

(1)先定义两个指针p1,p2,使p1 指向第一个节点,然后检查第一个节点的num值,如果不是我们想删除的节点,就后移动一个p2=p2->next;

  (2)在p1 向后移动之前,要把P1的值赋值给p2,让p2跟随p1的步伐,p2=p1;让p2 指向刚刚检查过的节点。

(3)p1一次次进行比较,然后向后移动,直到找到需要删除的节点或者压根就找不到要删除的节点,这里有两种情况; 

链表的动态建立,插入、删除节点学习记录

 

 

 

 

  (4) 情形1:找到了要删除的节点,根据节点所处的位置,由可以@R_22_6962@:是第一个节点非第一个节点;当要删除的节点是第一个节点的时候,很好办,直接将头指针向后移动一下即可;head=p1->next;如上图所示;

 

链表的动态建立,插入、删除节点学习记录

 

 

 

 

情形2:找到的这个节点,不在第一节点,那就把p1->next给p2->next;

 

(5) OK,上面就把要删除节点的大部分内容讲完了,接下来就是如果没有这个节点的情况了。没有这节点就直接输出no found 即可;

 

更为具体代码如下:

//删除节点
struct student* del(struct student* head, int  num)
{
    struct student* p1,*p2;    //定义两个指针
    if (head == NULL)
    {
        printf("这是一个空表\n"); return head;
    }
    
    p1 = head;
    p2 = NULL;
    while ((p1->num != num) && p1->next != NULL) //如果p1没有匹配上就跳过;
    {
        p2 = p1;
        p1 = p1->next;
    }
    
    if (p1->num==num)    //如果找到了这个节点,分两种情况
    {
        if (p1 == head)       //第一种,这个节点是头节点
        {
            head = head->next;
        }
        else               //第二种,这个节点非第一个节点
        {
            p2->next = p1->next;
            printf("delete num is %d\n", num);
            n--;                        //节点数减1;
        }
        
    }
    else //如果是最后一个也没匹配上,那么No found
    {
        printf("no found\n");

    }
    return head;
}

 

(三)链表的插入节点

 现在要新增一个学生的节点,按照学号大小,插入到已有的链表里面;

思路:

(1)首先新建立一个新的节点,输入这个学生的信息,这是必须的吧。

链表的动态建立,插入、删除节点学习记录

 

 

 

 

 (2)定义一个指针变量p0,让这个指针指向这个节点,如上图

链表的动态建立,插入、删除节点学习记录

 

 

 

 

(3)比较p1->num值与p0->num的大小,如果p1->num的数值小于p0->num,那么就让p1后移,并且让p2指向p1呆过的位置,如上图

链表的动态建立,插入、删除节点学习记录

 

 

 

 

(4)一直到p1->num 的值,小于了p0->num的值了,那么插入的位置找到了,接下来要开始插队了。这时候要分三种情况,在末尾和在头部和在中间;

  情形1:当不在中间的时候,很好办,直接把P0的值赋给p1->next; 把P1的值赋给p0->next;这样就插入了一个新节点进去了。

链表的动态建立,插入、删除节点学习记录

 

 

 

 

情形2:如果这个节点在末尾,将p0的赋给p1->next,NULL赋值给p0->next;

链表的动态建立,插入、删除节点学习记录

 

 

 

 

情形3:如果这个节点在头部,将p0赋值个head,将p1赋值给p0->next;

 

更为具体的代码如下:

 

//插入新节点
struct student* insert(struct student* head, struct student* stud)
{
    struct student* p0, * p1, * p2;
    p0 = stud;
    p1 = head;
    p2 = NULL;
    if (head == NULL)   //如果是一个空链表,那么把插入的这个节点作为头节点;
    {
        head = p0;
        p0->next = NULL;

    }
    while ((p0->num > p1->num) && (p1->next != NULL)) //当p0->num>p1->num时候,且p1后面还有数据时候,
//就让p1向后移动,并且p2跟随p1的步伐;
{ p2 = p1; p1 = p1->next; } if (p0->num < p1->num) //跳出while循环的条件之一:如果 p0->num < p1->num (也就是找到了插入的位置) { if (p1 == head) //如果这个节点在头部 { head = p0; //把P0插入到头节点 } else //这个节点在中间 { p2->next=p0; p0->next=p1; } } else //跳出while循环的条件之二: p1->next=NULL ,将p0插入到尾部; { p1->next=p0; p0->next = NULL; //把P0插入到尾部; } n++; //节点数+1; return head; }

 

 

OK 关于链表的动态建立,插入、删除节点就到这了

本文参 谭浩强的c程序设计;

大佬总结

以上是大佬教程为你收集整理的链表的动态建立,插入、删除节点学习记录全部内容,希望文章能够帮你解决链表的动态建立,插入、删除节点学习记录所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。
标签: