数据结构-单链表基本操作——C语言

一、按位插入(带头结点)ListInsert(&l,i,e)


  • Tips:(此时是 i=1 的情况,插在表头,不执行while循环 )
//在第i个位置插入元素 e (带头结点)
   typedef struct LNode{   //单链表结构定义
       ElemType data;  //存放数据域
       struct LNode *next; //指针域
   }LNode,*LinkList;
   {
      /* data */
   };
   
   bool ListInsert(LinkList &L,int i,Elemtype e){
      if(i<1) // 输入的i必须是合法的
        return false;
        LNode *p;   //指针p指向当前扫描到的结点
        int j=0;    //当前指针p指向的是第几个结点
        p=L;       //L指向头结点,头结点是第0个结点(不存储数据)
        while(p!=NULL && j<i-1)  {   //循环找到第i-1个结点
            p=p->next;
            j++;
        }
        if(p==NULL)  //i值不合法
         return false;
      LNode *s=(LNode *)malloc(sizeof(LNode));  //申请一个结点空间
      s->data=e;  //将参数e存储在新申请的结点里面
      s->next=p->next; //将s结点指向下一个结点的指针,指向p结点指向下一个结点的指针
      p->next=s;     // 将p结点指向下一个结点的指针指向s结点,即将结点连接到p之后
         return true;  //插入成功
   }

请添加图片描述

  • Tips:(当 i =3 时,是插入表中,while循环执行两次,与第一种情况基本类似,p指针往后移动两位 )

请添加图片描述

  • Tips:(当 i =5 时,是插入到表尾的情况,此时循环执行的次数最多,因此事时间复杂度也是最大)

请添加图片描述

  • Tips:(当 i =6 时,i >legth ,此时插入的位置超过了表长,p为NULL,不合法,因此return false)

请添加图片描述

二、按位插入(不带头结点)ListInsert(&l,i,e)

  • 思路:在表L中的第i个位置上插入指定元素e,先找到第i-1个结点,将新结点插入其后,但是由于没有头结点,因此i=1时需要特殊处理。
//在第i个位置插入元素 e (不带头结点)
   typedef struct LNode{   //单链表结构定义
       ElemType data;  //存放数据域
       struct LNode *next; //指针域
   }LNode,*LinkList;
   
   bool ListInsert(LinkList &L,int i,Elemtype e){
      if(i<1) // 输入的i必须是合法的
        return false;
     if(i==1){ //插入第1个结点的操作与其他结点操作不同
       LNode *s = (LNode*)malloc(sizeof(LNode)); //申请一个新结点
       s->data=e;  //将e存储在新结点的数据域
       s->next=L;  
       L=s;    // 头指针指向新结点
       return true;
     }
        LNode *p;   //指针p指向当前扫描到的结点
        int j=0;    //当前指针p指向的是第几个结点
        p=L;       //p指向第一个结点
        while(p!=NULL && j<i-1)  {   //循环找到第i-1个结点
            p=p->next;
            j++;
        }
        if(p==NULL)  //i值不合法
         return false;
      LNode *s=(LNode *)malloc(sizeof(LNode));  //申请一个结点空间
      s->data=e;  //将参数e存储在新申请的结点里面
      s->next=p->next; //将s结点指向下一个结点的指针,指向p结点指向下一个结点的指针
      p->next=s;     // 将p结点指向下一个结点的指针指向s结点,即将结点连接到p之后
         return true;  //插入成功
   }

请添加图片描述

  • Tips:(当 i>1 时,代码中间有点变化,其余逻辑和第一个是一样的)
 LNode *p;   //指针p指向当前扫描到的结点
        int j=1;    //当前指针p指向的是第1个结点
        p=L;       //p指向第1个结点(不是头结点)

三、指定结点的后插操作

  • 在结点p之后插入元素e
typedef struct LNode{
  ElemType data;
  struct LNode *next;
}LNode,*LinkList;
   bool InsertNexNode (LNode *p,ElemType e){
     if(p==NULL)  
         return false;
     LNode *s=(LNode *)malloc(sizeof(LNode));
     if (s==NULL)//内存分配失败(某些情况下是有可能的,比如内存不足)
         return false;
     s->data=e; //用结点s保存数据e
     s->next=p->next;
     p->next=s;  //将结点s连接到p之后
       return true;
   }

请添加图片描述

  • 如果要实现后插操作,只需要,先循环找到第i-1个结点,然后调用 renturn InsertNextNode (p,e); 这个函数即可。

四、前插操作

请添加图片描述

  • 因为线性表只能往后查询,前面是未知的,所以要考虑如何找到p的前驱结点,但是这种方法很麻烦,时间复杂度较大为 O(n)。

  • 另一种方法:

bool InsertPriorNode (LNode *p,ElemType e){
  if(p==NULL)
      return false;
  LNode *s = (LNode *)malloc(sizeof(LNode));
  if (s==NULL) //内存分配失败
      return false;
  s->next=p->next;
  p->next=s;   //新结点s连接到p之后
  s->data=p->data;  //将p中的元素复制到s中
  p->data=e;      //p中的元素覆盖为e
  return true;
}

请添加图片描述

  • 第三种方法:

请添加图片描述

按位序删除(带头结点)

  • ListDelete(&L,i,&e): 删除操作,删除表L中第i个位置的元素,并用e返回删除元素的值。(需要找到第 i-1个结点,修改指针并且用free函数释放第i个结点。

请添加图片描述

typedef struct LNode{   //单链表结构定义
       ElemType data;  //存放数据域
       struct LNode *next; //指针域
   }LNode,*LinkList;
   
   bool ListInsert(LinkList &L,int i,Elemtype e){
      if(i<1) // 输入的i必须是合法的
        return false;
        LNode *p;   //指针p指向当前扫描到的结点
        int j=0;    //当前指针p指向的是第几个结点
        p=L;       //L指向头结点,头结点是第0个结点(不存储数据)
        while(p!=NULL && j<i-1)  {   //循环找到第i-1个结点
            p=p->next;
            j++;
        }
     if(p==NULL) //i值不合法
         return false;
     if(p->next == NULL) //第i-1个结点后已无其他结点
        return false;
     LNode *q=p->next;   //令q指向被删除结点
     e = q->data;        //用e返回元素的值
     p->next=q->next;    //将*q结点从链中断开
       free(q);         //释放结点的存储空间
     return true;       //删除成功
   }

请添加图片描述

  • 删除指定结点:

请添加图片描述

(p结点如果是最后一个结点,那么会出错,会出现空指针)

请添加图片描述

(本节注意体会封装的好处)

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

无心er

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值