单链表插入新结点,编程

单链表插入新的结点,怎样操作?编程怎样实现?

链表插入本质上是,将“”插入节点“”的地址放入“上一个节点”内的指针处,将“下一个节点”的地址放入“插入节点”内的指针处。
楼上的例子是尾插,可以参考链接博客的插入部分。

七、链表结点的插入

1、算法描述

  给定一个链表头head,并且给定一个位置 $i(i \ge 0)$ 和 一个值 $v$,求生成一个值为 $v$ 的结点,并且将它插入到 链表 第 $i$ 个结点之后。

  • 首先,我们需要找到第 $i$ 个位置,可以利用上文提到的 链表结点的索引;然后,再执行插入操作,而插入操作分为两步:第一步就是 创建结点 的过程;第二步,是断开之前第 $i$ 个结点 和 第 $i+1$ 个结点之间的 "链",并且将创建出来的结点 "链接" 到两者之间。来看下动图演示。

    2、动画演示

    上图演示的是通过遍历,将数据为 8 的结点插入到链表第 1 个(下标从 0 开始)结点后的过程,其中:
      head 代表链表头结点;
      tail 代表链表尾结点;
      pre 代表待插入结点的 前驱结点,也是 游标指针 指代的结点,即动图中的 橙色实心结点
      aft 代表 待插入结点后继结点,即动图中的 蓝色实心结点
      vtx 代表将要插入的结点,即动图中的 绿色实心结点

    3、源码详解

    ListNode *ListInsertNode(ListNode *head, int i, DataType v) {
      ListNode *pre, *vtx, *aft;                     // (1) 
      int j = 0;                                     // (2) 
      pre = head;                                    // (3) 
      while(pre && j < i) {                          // (4) 
          pre = pre->next;                           // (5) 
          ++j;                                       // (6) 
      }
      if(!pre) { 
          return NULL;                               // (7) 
      }
      vtx = ListCreateNode(v);                       // (8) 
      aft = pre->next;                               // (9)
      vtx->next = aft;                               // (10)
      pre->next = vtx;                               // (11)
      return vtx;                                    // (12)  
    }
    
  • $(1)$ 预先定义三个指针,当结点插入完毕后, pre -> vtx -> aft
  • $(2)$ 定义一个计数器,当 j == i时,表明找到要插入的位置;
  • $(3)$ 从 链表头结点 开始迭代遍历链表;
  • $(4)$ 如果还没有到链表尾,或者没有找到插入位置则继续循环;
  • $(5)$ 将 游标指针后继结点 作为新一轮的 游标指针,继续迭代;
  • $(6)$ 计数器加 1;
  • $(7)$ 元素个数不足,无法找到给定位置,返回 NULL;
  • $(8)$ 创建一个值为v孤立结点
  • $(9) \to (11)$ 这三步就是为了将vtx插入到pre -> aft之间,插入完毕后pre -> vtx -> aft
  • $(12)$ 最后,返回插入的那个结点;

主要逻辑如下:

struct StNode 
{
    int data;
    struct StNode* next;
};

//插入
StNode* InsertNode(struct StNode* head,int v)
{
    struct StNode* p,*t;
    //创建新节点
    t = (struct StNode*)malloc(sizeof(StNode));
    t->data = v;
    t->next = NULL;

    if(head == NULL) return t;
    //将节点插入到尾部:1.找到最后一个节点
    p = head;
    while(p->next)
        p = p->next;
    //2.插入
    p->next = t;
    return head;

}