链表笔记(2)

继上一章继续讲解,这一随笔主要记录的链表的删除与链表的插入。

  1. 链表的删除  :删除链表中指定的数据,一般需要经过三个步骤              
  • 定位:采用遍历思想,在链表中查找待删除数据所在的结点位置,并用一个指针保存该位置
  • 脱链:“脱离”,且剩下结点仍要维持链表关系
  • 释放:释放待删除结点的内存空间
  • 注释:

         

例题:在上一例题的基础上增加删除函数Delete

#include<stdio.h>
#include<stdlib.h>
struct Node
{
    int data;
    struct Node *next;
 };
 typedef struct Node Node;
 Node * Create();
 void Print(Node *head);
 void Release(Node *head);
 Node * Delete(Node *head,int num);//待删除数据值,函数返回值为删除后的头指针
int main()
 {
     int num;
     Node *head;      //定义一个头指针
    head=Create();   //创建新链表,返回的头指针赋值给head
    Print(head);     //遍历,输出每个元素的值
    printf("请输入要删除的数据:
") ;
    scanf("%d",&num);
    head=Delete(head,num);
    Print(head); 
    Release(head);
    return 0; 
 }

//函数定义

Node * Create()
 {
     Node *head,*tail,*p;  //head,tail分别指向头结点和尾结点 
     int num;
    head=tail=NULL;      //链表初始化:空链表
    printf("请输入一批数据,以-999结尾:
");
    scanf("%d",&num);
    while(num!=-999)  //用户输入未结束
    {
        p=(Node *)malloc(sizeof(Node));   //申请一块结点的内存用于存放数据
        p->data=num;                      //将数据存于新结点的data成员中 
        p->next=NULL;                     //将新结点的指针赋为空值
        if(head==NULL)                    //如果原来链表为空值
        {
            head=p;                       //将P值复制给head,p是刚申请的第一个结点 
         } 
        else
        {
            tail->next=p;                 //如果原来链表为非空 
        } 
        tail=p;                           //更新tail指针,让其指向新的结尾处
        scanf("%d",&num); 
     } 
     return head;                        //返回链表的头指针 
      
 }
 void Print(Node * head)
 {
     Node *p;                             //定义工作指针P
    p=head;                               //p从头指针开始
    if(NULL==head)                       //如果链表为空输出提示信息
    {
        printf("链表为空
");
    }
    else
    {
        printf("链表如下:
");
        while(p!=NULL)               //p为空指针时则停止
        {
            printf("%d",p->data);
            p=p->next;
         } 
     } 
     printf("
");
     
 }
 
 void Release(Node *head)
 {
     Node *p1,*p2;                   //p1控制循环,p2指向当前删除结点处
    p1=head;
    while(p1!=NULL)
    {
        p2=p1;                     //p2指向当前删除结点处
        p1=p1->next;               //p1指向下一结点
        free(p2); 
    }
    printf("链表释放成功!"); 
 }

//重点:Delete函数定义

Node * Delete(Node *head,int num)
 {
     Node *p1,*p2;
     if(NULL==head)  //空链表判断
     {
         printf("链表为空!
");
         return head;
      } 
    p1=head;        //p1用于查找待删除结点,从头指针开始
    while(p1->next &&p1->data!=num)     
    {
        p2=p1;      //p2用于记下原来p1的值 
        p1=p1->next;
    } 
    if(p1->data==num)   //找到该数据
    {
        if(head==p1)    //如果删除的是第一个结点
        {
            head=p1->next;
         } 
         else
         {
             p2->next=p1->next;
         }
         free(p1);
         printf("删除成功!
");
     }
     else
     printf("链表中无次数据!
");
     return head; 
 }

   2、链表的插入:

  • 若链表中的数据是从小到大存放的,现要求向链表中插入一个结点,并保存数据是从小到大的次序不变
  • 三个步骤:(1)生成结点:与创建链表类似,要添加一个新数据,先要动态分配内存的方法生成一个结点,将新数据复制给该点数据域,而该结点的指针域则设为NULL 

                            (2)确定位置:遍历查找,确定位置

                            (3)插入结点:将该节点插入链表

例题:在第一个随笔的例题下添加Insert函数

include<stdio.h>
#include<stdlib.h>
struct Node
{
    int data;
    struct Node *next;
 };
 typedef struct Node Node;
 Node * Create();
 void Print(Node *head);
 void Release(Node *head);
 Node * Insert(Node *head,int num);
int main()
 {
     int num;
     Node *head;      //定义一个头指针
    head=Create();   //创建新链表,返回的头指针赋值给head
    Print(head);     //遍历,输出每个元素的值
    printf("请输入要插入的数据:
") ;
    scanf("%d",&num);
    head=Insert(head,num);
    Print(head); 
    Release(head);
    return 0; 
 }
 Node * Create()
 {
     Node *head,*tail,*p;  //head,tail分别指向头结点和尾结点 
     int num;
    head=tail=NULL;      //链表初始化:空链表
    printf("请输入一批数据,以-999结尾:
");
    scanf("%d",&num);
    while(num!=-999)  //用户输入未结束
    {
        p=(Node *)malloc(sizeof(Node));   //申请一块结点的内存用于存放数据
        p->data=num;                      //将数据存于新结点的data成员中 
        p->next=NULL;                     //将新结点的指针赋为空值
        if(head==NULL)                    //如果原来链表为空值
        {
            head=p;                       //将P值复制给head,p是刚申请的第一个结点 
         } 
        else
        {
            tail->next=p;                 //如果原来链表为非空 
        } 
        tail=p;                           //更新tail指针,让其指向新的结尾处
        scanf("%d",&num); 
     } 
     return head;                        //返回链表的头指针 
      
 }
 void Print(Node * head)
 {
     Node *p;                             //定义工作指针P
    p=head;                               //p从头指针开始
    if(NULL==head)                       //如果链表为空输出提示信息
    {
        printf("链表为空
");
    }
    else
    {
        printf("链表如下:
");
        while(p!=NULL)               //p为空指针时则停止
        {
            printf("%d",p->data);
            p=p->next;
         } 
     } 
     printf("
");
     
 }
 
 void Release(Node *head)
 {
     Node *p1,*p2;                   //p1控制循环,p2指向当前删除结点处
    p1=head;
    while(p1!=NULL)
    {
        p2=p1;                     //p2指向当前删除结点处
        p1=p1->next;               //p1指向下一结点
        free(p2); 
    }
    printf("链表释放成功!"); 
 }
View Code

//重点:Insert函数定义

Node * Insert(Node *head,int num)
 {
     Node *p1,*p2,*p;
     p=(Node *)malloc(sizeof(Node));//为待插入的数据申请一块内存
     p->data=num;
     p->next=NULL;
     p1=head;
     while(p1 &&p->data >p1->data)  //确定插入位置
     {
         p2=p1;
         p1=p1->next;
      } 
      if(p1==head)
      {
          head=p;
      }
      else
      {
          p2->next=p1;
      }
      p->next=p1;
      printf("插入数据成功!
");
      return head;
}

                   

    

原文地址:https://www.cnblogs.com/8098pc/p/12769743.html