编程导航算法通关村第一关|链表青铜挑战

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

— 链表基础整理

一、链表基础概念

链表的基本结构类似于铁链
在这里插入图片描述
由一个又一个的节点-在Java中即为一个又一个的对象引用,相互嵌套形成。
根据这一特点,可以定义出链表的对象模型:

@Data
public class Node {
    /** 节点包含的数据值 */
    private int data;
    /** 指向下个节点的对应引用 */
    private Node next;

    public Node(int data) {
      this.data = data;
      // 这一行本质上没什么用,写出来只是为了看的更清晰
      this.next = null;
    }
}

二、链表增加元素,首部,中部,尾部分别会有什么问题

链表插入元素逻辑如下:

/**
   * 链表插入
   *
   * @param head
   *     头节点
   * @param nodeInsert
   *     插入节点
   * @param position
   *     插入位置 从1开始;
   * @return 新的头节点
   */
  private static Node insertLinkedList(Node head, Node nodeInsert, int position) {
    if (head == null) {
      // 头节点不存在,插入节点直接成为头节点,并且没有后续节点指向
      head = nodeInsert;
    }

    // 判断插入位置是否越界
    int size = getLinkedListLength(head);
    if (position > size + 1 || position < 1) {
      System.out.println("插入位置越界");
      return head;
    }

    // 在头节点插入
    if (position == 1) {
      //插入节点为新的头节点,插入节点的后续节点指向原来的头节点
      nodeInsert.next = head;
      // 这里可以直接返回nodeInsert,也可以把nodeInsert的引用重新赋值给head,从字面意思上更好理解,head依然是头节点
      head = nodeInsert;
      return head;
    }

    // 中部插入(包含尾部插入):原理是获取到要插入位置的前一个节点A,然后通过将插入节点连接到节点A之后,并且将插入节点的后续节点指向原来的节点A的后续节点,以此实现链表插入
    Node cur = head;
    int count = 1;
    while (count < position - 1) {
      // 从头节点开始遍历,直到获取到节点A
      cur = cur.next;
      count++;
    }
    // 将插入节点的后续节点指向节点A已有的后续节点
    nodeInsert.next = cur.next;
    // 修改节点A的后续节点为插入节点
    cur.next = nodeInsert;

    return head;
  }

1.头部插入的问题

在头部插入需要注意插入后原来的头节点已经不再是头节点,而是新插入的节点成为头节点。
当然,从上述代码上看,头节点依然是head,但实际上这个head指向的内存地址已经更改成插入节点的内存地址

2.中部/尾部插入的问题

在中部/尾部插入的时候需要注意节点丢失。
首先要先找到插入节点应该在的位置,然后获取到前一个节点信息。注意这里不能获取后一个节点,如果拿到的是后一个节点信息的话,再后续交换指向节点的时候就会丢失原节点的信息。
例如,原链表数据:1,2,3,4,5,6;
现在要在position = 3的位置上插入一个新的节点:2.5;链表从1开始计算
这种情况下,我们需要获取的是Node(2)的信息,根据Node(2)的节点信息,将插入节点进行关联。


三、链表删除元素,首部,中部,尾部分别会有什么问题

链表删除元素逻辑:

private static Node removeLinkedList(Node head, int position) {
    if (head == null) {
      return null;
    }

    int size = getLinkedListLength(head);
    if (position > size || position < 1) {
      System.out.println("要移除的位置越界");
      return head;
    }

    if (position == 1) {
      // 头节点移除,只需要将head的引用调整成head原先的后续节点即可
      head = head.next;
    } else {
      Node cur = head;
      int count = 1;
      while (count < position - 1) {
        cur = cur.next;
        count++;
      }

      Node curNode = cur.next;
      cur.next = curNode.next;
    }
    return head;
  }

删除节点需要注意的地方和新增节点一致

双向链表构造以及新增删除逻辑

todo

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值