9.8单链表之增、删、改、查

9.8单链表之增、删、改、查

单链表操作分类


链表中插入元素

插入的分类:

  • 插入到链表的头部(头节点之后),作为首元节点;

  • 插入到链表中间的某个位置;

  • 插入到链表的最末端,作为链表中最后一个数据元素;

插入需要执行的步骤:

  • 步骤1:将新结点的 next 指针指向插入位置后的结点

  • 步骤2:将插入位置前结点的 next 指针指向插入结点

链表插入节点的图示:

链表插入元素的操作必须是先步骤 1,再步骤 2;反之,若先执行步骤 2,除非再添加一个指针,作为插入位置后续链表的头指针,否则会导致插入位置后的这部分链表丢失,无法再实现步骤 1

链表插入数据

  • 首元节点前

  • 中间

  • 最后一位


首元节点前插入元素代码示例:

/*
形参传入:
1、原链表
2、插入新数据的数据域元素
3、要插入的位置
*/
link * insertLink(link * p, int element, int index){
   //创建一个临时节点
   link * temp = p;
   for(int i=1; i<index; i++){ //这个i全程只是用来找节点的
       //如果传入的节点是一个头指针或者头元素--->插入失败、结束、返回
       temp = temp->next; //拿到原链表的指针域--->本质是一个其他节点
       /*
       每一次都更改
       */
       if(temp == null){
           printf("原链表有误");
           return p; //结束方法,返回原链表
  }
  }
   
   //如果原链表正确。创建插入节点
   link * c = (link*)malloc(sizeof(link));
   /*插入节点的数据域为传入的数据*/
   c->elem = element;
   /*插入节点的指针域为循环找到的插入节点的指针域*/
   c->next = temp->next;
   /*临时节点指针域赋值给创建节点*/
   temp->next = c;
   //返回头指针
   return p;
}

链表删除元素

链表中删除元素需要注意释放掉摘掉的节点。需要注意一下两步:

  • 将结点从链表中摘下来;

  • 手动释放掉结点,回收被结点占用的存储空间;--->从链表上摘下的节点通过 free 函数进行释放

更改节点指向的代码非常简单:

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

更改节点指向图示:

删除节点代码示例:

//p为原链表,value为要删除元素的值
link * delElem(link * p, int value) {
   link * temp = p;
   //遍历到被删除结点的上一个结点
   for (int i = 1; i < value; i++) {
       temp = temp->next;
       if (temp->next == NULL) {
           printf("没有该结点\n");
           return p;
      }
  }
   link * del = temp->next;//单独设置一个指针指向被删除结点,以防丢失
   temp->next = temp->next->next;//删除某个结点的方法就是更改前一个结点的指针域
   free(del);//手动释放该结点,防止内存泄漏
   return p;
}

链表查找元素

实现方法:

  • 从表头依次遍历表中节点

  • 用被查找元素与各节点数据域中存储的数据元素进行比对,直至比对成功或遍历至链表最末端的 NULL(最后一个节点的指针域)

示例代码:

/*
1、link*p是原链表
2、int elem表示被查找的元素
*/
Link * selectEle(Link * p, int elem){
   //创建临时节点存储链表
   Link * temp = p;
   /*使用while循环:循环初始值、循环控制域、循环结束条件*/
   int i=1; //--->从1开始是为了越过头节点
   //判断条件为:--->节点的指针域存在,存在进入循环
   while (temp->next)
  {
       //节点域名存在,将下一个节点域赋值给当前节点
       temp=temp->next;
       //判断当前的数据域是否与要查找的元素相等
       if (temp->elem==elem)
      {
           //返回当前的循环的节点
           return i;
      }
       i++;
  }
   //执行到这里无返回则表示失败
   return -1;
}

遍历有头节点的链表时,避免头节点的影响,在遍历链表时,直接越过头节点对链表进行有效遍历。--->int i = 1

链表更新元素

具体实现:

  • 遍历找到存储此元素的节点

  • 对该节点当中的数据域进行修改

/*
1、传入原链表
2、传入要更改的节点在链表中的位置
3、传入更新的数据域的数据
*/
Link * updateEle(Link * p, int index, int newEle){
   /*创建临时节点,存储原链表*/
   Link * temp = p;
   //开始遍历之前将temp指向首元节点
   temp = temp->next;
   //遍历找到希望更新的节点
   for (int i = 1; i < index; i++)
  {
       temp = temp->next; //找到更新的节点
  }
   temp->elem = newEle;
   //返回原链表
   return p;
}
posted @ 2021-09-09 19:26  俊king  阅读(136)  评论(0编辑  收藏  举报